Flutter Remove Dispose Delete Widget by User

Issue

I have a GridView.builder.
Inside I have TextButtons which the user can add with their chosen name and color.

onLongPress: activates an AllertDialog which asks the user to delete the Button. However, it does not delete with a Callback (deleteCallback) nor Provider.

also, I don’t get any error 🙁

this is the code for the Grid

    import 'package:flutter/material.dart';
import 'package:cards/widgets/mycard_tile.dart';
import 'package:provider/provider.dart';
import 'package:cards/Models/card_data.dart';

class CardsList extends StatelessWidget {
  const CardsList({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Consumer<MyCardData>(
      builder: (context, cardData, child) {
        return Padding(
          padding: const EdgeInsets.all(10),
          child: GridView.builder(
            clipBehavior: Clip.none,
            itemBuilder: (context, index) {
              final card = cardData.cards[index];
              return CardTile(
                cardTitle: card.name,
                pickerColor: card.cardColor,
                deleteCallback: () {
                  **cardData.deleteCard(card);**
                  Navigator.pop(context);
                },
              );
            },
            itemCount: cardData.cardCount,
            gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 150,
              childAspectRatio: 2.5 / 1,
              crossAxisSpacing: 10,
              mainAxisSpacing: 10,
            ),
          ),
        );
      },
    );
  }
}

this is the code where I store the core Button Data

    import 'dart:ui';

import 'package:cards/Screens/add_card.dart';
import 'package:flutter/foundation.dart';
import 'package:cards/Models/card.dart';
import 'dart:collection';

import 'package:flutter/material.dart';


class MyCardData extends ChangeNotifier {
  final List<MyCard> _cards = [
    MyCard(name: 'TAG', cardColor: Colors.red),
    MyCard(name: 'Nachtdienst', cardColor: Colors.blue),
    MyCard(name: 'Kurz', cardColor: Colors.orange),
    MyCard(name: 'NG\'s', cardColor: Colors.grey),
    MyCard(name: 'Urlaub', cardColor: Colors.green),
    MyCard(name: 'Fortbildung', cardColor: Colors.pink),
    MyCard(name: 'Lang minus', cardColor: Colors.red.shade800),
    MyCard(name: 'reserve', cardColor: Colors.black),
  ];

  UnmodifiableListView<MyCard> get cards {
    return UnmodifiableListView(_cards);
  }

  int get cardCount {
    return _cards.length;
  }

  get cardColor => pickerColor;

  void addCard(String newMyCardTitle, Color newCardColor,) {
    final card = MyCard(name: newMyCardTitle, cardColor: cardColor);
    //pickerColor = newCardColor as Color; //redundant?
    _cards.add(card);
    notifyListeners();
  }

  **void deleteCard(MyCard card) {
    _cards.remove(card);
    notifyListeners();
  }**
}

this is where i store the Design and where the Button is placed

please ignore TODO’s

import 'package:cards/Models/card.dart';
import 'package:cards/Screens/add_card.dart';
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:cards/Models/card_data.dart';
import 'package:provider/provider.dart';

class CardTile extends StatelessWidget {
  late String cardTitle;
  Color pickerColor;
  final Function **deleteCallback;**

  CardTile(
      {required this.cardTitle,
      required this.pickerColor,
      required this.**deleteCallback**});

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onLongPress: () => showDialog<String>(
        context: context,
        builder: (BuildContext context) => AlertDialog(
          actionsAlignment: MainAxisAlignment.spaceEvenly,
          title: Center(
            child: Text(
              cardTitle,
              style: TextStyle(color: pickerColor),
            ),
          ),
          content: const Text(
            'Möchtest du die Karte wirklich löschen?',
            textAlign: TextAlign.center,
            style: TextStyle(
              fontSize: 18,
            ),
          ),
          actions: <Widget>[
            TextButton(
              style: ButtonStyle(
                  shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                      RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  )),
                  elevation: MaterialStateProperty.all(10),
                  backgroundColor: MaterialStateProperty.all(Colors.white)),
              onPressed: () {
                **deleteCallback; // This does not work! >>>>>>>>>>>>>>>>>>>>>>>>> this is where I need help <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<**
              },
              child: const Text(
                'Delete Card!',
                style: TextStyle(color: Colors.black),
              ),
            ),
            TextButton(
              style: ButtonStyle(
                shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                    RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                )),
                elevation: MaterialStateProperty.all(10),
              ),
              onPressed: () => Navigator.pop(context),
              child: const Text(
                'Cancel!',
                style:
                    TextStyle(color: Colors.black, fontWeight: FontWeight.bold),
              ),
            ),
          ],
        ),
      ),
      onPressed:
          () {}, //TODO: Activate Button > Button should give forward information > Button name and color of tile > to sfCalendar, also change the appearance of button when active
      style: ButtonStyle(
          shape: MaterialStateProperty.all(
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(8))),
          backgroundColor: MaterialStateProperty.all(pickerColor),
          elevation: MaterialStateProperty.all(10)),
      child: FittedBox(
        fit: BoxFit.fitHeight,
        child: Text(
          cardTitle,
          style: TextStyle(
            fontSize: 17,
            color: useWhiteForeground(pickerColor)
                ? const Color(0xffffffff)
                : const Color(0xff000000),
          ),
        ),
      ),
    );
  }
}

you can see the full code on my git

Solution

when you pass a Function, you have to use it a function too. Which is you need to add () at the end.

 onPressed: () {
   // here you can add another thins you want to execute 
    **deleteCallback();  // add this:  () 
 },

but if you only have 1 funtion you can use is without ()
eg:

class CardTile extends StatelessWidget {
  final VoidCallback deleteCallback;

  CardTile({
     required this.deleteCallback });

...
// and you can use it 
  backgroundColor: MaterialStateProperty.all(Colors.white)),
  onPressed : deleteCallback, // its directly assign, without use () {}
  child: ....

Answered By – pmatatias

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *