Search code examples
flutterflutter-animation

Flutter: Animate Conditional Items Added to Row


I have a stateless widget in Flutter that responds to changes to a property in a Provider model. When I click on an "edit" button, I toggle a boolean in my model and my reminders go into edit mode like this:

reminders

Here's a simplified version of my code:

Widget build(BuildContext context) {
  //A boolean from my model
  var editMode = Provider.of<ModelDashboard>(context).sidebarEditMode;

  return Column(
    children: [
      Container(
        padding: EdgeInsets.fromLTRB(editMode ? 5 : 15, 15, editMode ? 5 : 15, 12),
        child: Row(
          children: [
            if (editMode) ...[
              PPReorder(
                index: index,
              ),
              const SizedBox(width: 5),
            ],
            //Rest of row...
          ],
        ),
      ),
    ]
  );
}          

So as editMode changes, it adjusts some padding and shows/hides a couple elements in my row.

I looked at some of the animation options and they don't seem right to me:

  • AnimatedContainer - I tried animating the width to 0 and I got overflow errors.
  • AnimatedOpacity - The item still takes up space when its opacity is 0.
  • AnimatedPositioned - My items are not positioned within a Stack.

What would be the appropriate way to animate the appearance of these conditional items in my Row?


Solution

  • For this you can use AnimatedCrossFade. I had almost same situation where I need to show and hide one element with animation and AnimatedCrossFade is easiest and best way to implement animation.

    Widget build(BuildContext context) {
      //A boolean from my model
      var editMode = Provider.of<ModelDashboard>(context).sidebarEditMode;
    
      return Column(
          children: [
            Container(
              padding: EdgeInsets.fromLTRB(editMode ? 5 : 15, 15, editMode ? 5 : 15, 12),
              child: Row(
                children: [
                  AnimatedCrossFade(
                    duration: const Duration(seconds: 3),
                    firstChild: Row(
                      children: [
                        PPReorder(
                          index: index,
                        ),
                        const SizedBox(width: 5),
                      ],
                    ),
                    secondChild: Container(),
                    crossFadeState: editMode
                        ? CrossFadeState.showFirst
                        : CrossFadeState.showSecond,
                  )
                  //Rest of row...
                ],
              ),
            ),
          ]
      );
    }
    

    You can play around with this as per your requirments.