Flutter Slidable stays open after item is removed from list

1,998

You should assign a key to your slidables. When Flutter manages its state it uses three trees to do it: a widget tree, element tree and render object tree. When a widget dismiss flutter tries to sync the rest widgets with the corresponding elements by simple type equality. So, that's why your app behaves this way. Flutter takes the first remaining widget plus the first element and compares whether they have the same type. If they have then Flutter uses the state of the element to show the corresponding render object. The last element of the element tree will be just dropped. So, you need to add keys and Flutter will additionally use them to sync widgets and elements in a desirable way.

Each Flutter widget has a Key field. You should assign them when you creating a widget instance. You can use some utility classes to generate such a key - like ValueKey(), UniqueKey etc. Alternatively, you can use you own keys if you have it in your data.

Share:
1,998
Chris
Author by

Chris

Updated on December 31, 2022

Comments

  • Chris
    Chris about 1 year

    I am using Slidable inside a ListView so I can delete items. The problem is that if I remove an item from the list, the new item has its slidable open. That is obviously not the desired behavior. Here is a Screenvideo for a better understanding.

    My list is an AnimatedList:

    
    `                       child: AnimatedList(
                                padding: EdgeInsets.zero,
                                shrinkWrap: true,
                                key: listKey,
                                initialItemCount: widget.month.memories.length,
                                itemBuilder: (context, index, animation) {
                                  return slideIt(
                                    context,
                                    widget.month.memories[index],
                                    index,
                                    animation,
                                  );
                                },
                              ),`
    

    And for here is my Slidable:

    ` Widget slideIt(
        BuildContext context,
        Memory memory,
        int index,
        animation,
      ) {
        return SlideTransition(
          position: Tween<Offset>(
            begin: const Offset(-1, 0),
            end: Offset(0, 0),
          ).animate(
            CurvedAnimation(
              parent: animation,
              curve: Curves.easeIn,
              reverseCurve: Curves.easeOut,
            ),
          ),
          child: Slidable(
            actionPane: SlidableDrawerActionPane(),
            actionExtentRatio: 0.25,
            movementDuration: Duration(milliseconds: 400),
            child: Column(
              children: [
                MemoryTile(
                  memory: memory,
                  monthName: widget.month.name,
                  onTapped: () {
                    _removeMemoryAtIndex(index, memory);
                    print('tap on ${memory.description}');
                  },
                ),
                SizedBox(
                  height: scaleWidth(20),
                ),
              ],
            ),
            secondaryActions: [
              SlideAction(
                closeOnTap: false,
                color: AppColors.secondary,
                onTap: () => {
                  _removeMemoryAtIndex(index, memory),
                },
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Icon(
                      CupertinoIcons.trash_fill,
                      color: AppColors.primary,
                      size: 30,
                    ),
                    SizedBox(
                      height: scaleWidth(5),
                    ),
                    Text(
                      'Löschen',
                      style: AppTextStyles.montserratH6SemiBold,
                    ),
                    SizedBox(
                      height: scaleWidth(20),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      }`
    

    The AnimatedList makes it a bit more tricky so let me know if you need any more info! How can I fix this?

  • Chris
    Chris over 2 years
    thanks for your answer! I am quite new to flutter so, how do I add keys? :D
  • Chris
    Chris over 2 years
    nvm, I got it: key: Key(memory.description), adding this in the Slidable fixed it! Thanks man :)
  • Yuri Heiko
    Yuri Heiko over 2 years
    @Chris I added it to my answer anyway :)