user11934987
user11934987

Reputation:

How do I remove a widget in response to user input?

I have a chip. How do I get the chip to disappear when the user has deleted it? I do not understand the code at all from Flutter Docs.

I've tried everything.

Chip(
 deleteIcon:  Icon(Icons.close, size: 15,),
 label: Text('Delete me!'),
 deleteButtonTooltipMessage: 'erase',
 onDeleted: () {setState(() {print("I want to erase this chip, and     eat chips");}); },
)

The docs suggest that this chip (Chip) can be erased. But they don't give much in the way of examples.

Upvotes: 1

Views: 2014

Answers (3)

Son of Stackoverflow
Son of Stackoverflow

Reputation: 1679

bool isDeleted = false; // Place the variable within the same class or declare them as global variables
//[...]
    (isDeleted)?Container():Chip(
     deleteIcon:  Icon(Icons.close, size: 15,),
     label: Text('Delete me!'),
     deleteButtonTooltipMessage: 'erase',
     onDeleted: () {setState(() {isDeleted=true;}); },
    )
//[...]

isDeleted is a boolean variable which stores either true or false.

If you see your main code (which you haven't provided as it wasn't needed) there is an build method which we override in order to implement/return a single Widget(UI).

The build method called whenever setstate is called or 60 times a second while playing a animation (60 fps).

So when we attempt to delete a Chip, the onDeleted method is triggered which in turn triggers setstate() function which first makes the required changes mentioned in the function we pass as a parameter and it then requests the app to call the build function again.

In our case, when our Widget is first built the app sees that the ternary condition's final result is false so it builds the second widget, i.e. the Chip widget. Now when setState is called the value of onDeleted changes to true and then the build function is called again. But this time since the value of onDeleted is true the first widget is built i.e a Container with no dimensions...equivalent to having nothing there(But we use it since we cannot leave it empty as it will lead to some error(s) depending on how you use the code).

Now you might wonder why don't we realize/notice anything while all this happens...

It's because an average human can notice any change only if that change takes more than 200 milliseconds to happen. If it is faster(takes lesser than 200ms) than that then we view those changes as an animation/transition. If those changes take more time to occur, then we feel that the app is lagging.

That is why keeping Stateful widgets separate increases the app's overall performance as we won't rebuild the widgets which don't need to get rebuilt as they'll remain Stateless.

I hope your doubts are now cleared.

Upvotes: 0

Karim Elghamry
Karim Elghamry

Reputation: 1421

you need to set a flag or a bool which indicates whether the Chip is deleted or not.

Working Example

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDeleted = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: _isDeleted
              ? Container()
              : Chip(
                  label: Text("EMINEM"),
                  onDeleted: () {
                    setState(() {
                      _isDeleted = true;
                    });
                  },
                ),
        ),
      ),
    );
  }
}

Output

sample

Upvotes: 1

creativecreatorormaybenot
creativecreatorormaybenot

Reputation: 126654

I am assuming that you have this Chip in some kind of StatefulWidget.

class DisappearingChip extends StatefulWidget {
  const DisappearingChip({Key key}) : super(key: key);

  @override
  State createState() => _DisappearingChipState();
}

class _DisappearingChipState extends State<DisappearingChip> {
  bool erased;

  @override
  void initState() {
    erased = false;
    super.initState();
  }

  @override
  Widget build(BuildContext context) => erased
      ? Container()
      : Chip(
          deleteIcon: Icon(
            Icons.close,
            size: 15,
          ),
          label: const Text('Delete me!'),
          deleteButtonTooltipMessage: 'erase',
          onDeleted: () {
            setState(() {
              erased = true;
            });
          },
        );
}

Variable responding to state

As you can see, the State object holds a bool called erased that is assigned false when the state is initialized.
When the Chip is meant to be deleted now, this variable is updated and the widget rebuilds. As it responds to the value of erased, an empty Container is returned once the Chip is deleted.


I recommend this resource to learn more.

Upvotes: 2

Related Questions