How to change row/column states with animation in Flutter?
Asked Answered
V

3

5

I am using rows and columns in my layout and load some data from the internet to display information inside my rows and columns.

I want to design a dynamic loading page in such a way that every loaded data makes a particular widget visible with an animation (by moving the other widgets around smoothly).

I am currently using if clauses inside my layouts and calling setState() when new data is retrieved.

Column(
  children: [
    SomeWidget(),
    if (data != null)
      DataWidget(),
    AnotherWidget(),
  ],
),

How can I insert widgets between other widgets in rows/columns with animation after some data is retrieved?

Villada answered 27/4, 2021 at 0:49 Comment(0)
B
5

Flutter already has tons of useful widgets which you can use for this implementation. I believe that the AnimatedList widget solves your problem. I have added the widget of the week video and a basic example below.

Widget of the Week - AnimatedList

Example:

import 'package:flutter/material.dart';

class PageOne extends StatefulWidget {
  @override
  _PageOneState createState() => _PageOneState();
}

class _PageOneState extends State<PageOne> {
  /// The global key to access the animated list.
  final _animatedListKey = GlobalKey<AnimatedListState>();

  List<String> _items = [];

  @override
  void initState() {
    // Set the items that should be display.
    _items = ['A', 'B', 'D', 'E', 'F'];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Example')),
      body: AnimatedList(
        key: _animatedListKey,
        initialItemCount: _items.length,
        itemBuilder: (context, index, animation) {
          return SlideTransition(
            position: animation.drive(
              // Tween that slides from right to left.
              Tween(begin: Offset(1.0, 0.0), end: Offset(0.0, 0.0)),
            ),
            // Simply display the letter.
            child: ListTile(title: Text(_items[index])),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          // The item to insert.
          final _item = 'C';

          // Add, sort, and retrieve the index of the inserted item.
          List<String> _temp = _items..add(_item);
          _temp.sort();
          final _index = _temp.indexOf(_item);

          // Update the state and start the animated list animation.
          setState(() {
            _items.insert(_index, _item);
            _animatedListKey.currentState?.insertItem(_index);
          });
        },
      ),
    );
  }
}

Baden answered 29/4, 2021 at 20:3 Comment(2)
Thank you, this is probably the best approach for me. But do you know any way to insert list items by giving them some priority? For example, I want item C to be placed before D, E and after A, B. The problem is that the available items in the list may vary when C arrives.Villada
Yes that is certainly possible! I have added a basic implementation of what you are asking. Let me know if anything is unclear.Baden
S
2

You can use AnimatedSize together with SizeBox. Here's how it will look like on your example:

Column(
  children: [
    SomeWidget(),
    AnimatedSize(
      duration: Duration(seconds: 1),
      child: SizeBox(
        height: data == null ? 0 : null,
        child: DataWidget()
      )
    ),
    AnotherWidget(),
  ],
),

Important: if you don't specify a height in SizeBox, the animation will only extend to the width.

Shererd answered 25/6, 2024 at 7:9 Comment(0)
W
-1

you can always use AnimatedSwitcher to animate between widgets, just setState and change _widget:

AnimatedSwitcher(
  duration: Duration(milliseconds: 200),
  transitionBuilder: (Widget child, Animation<double> animation) {
    var tween=Tween<Offset>(begin: Offset(1, 0), end: Offset(0, 0))
     return SlideTransition(
       child: child,
       position: tween.animate(animation),
    );
  },
  child: _widget,
)

OR using flutter_staggered_animations with Column & Row showing animation

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: AnimationLimiter(
          child: Column(
            children: AnimationConfiguration.toStaggeredList(
              duration: const Duration(milliseconds: 375),
              childAnimationBuilder: (widget) => SlideAnimation(
                horizontalOffset: 50.0,
                child: FadeInAnimation(
                  child: widget,
                ),
              ),
              children: YourColumnChildren(),
            ),
          ),
        ),
      ),
    );
  }
Westering answered 27/4, 2021 at 2:21 Comment(2)
But isn't AnimatedSwitcher for switching between two different widgets? I want my widgets to appear out of nowhere. Is there a better practice for this or do I need to set AnimatedSwitcher's child as an empty Container and then switch it to the widget I want?Villada
I've edited my answer, is this what you want? flutter_staggered_animationsWestering

© 2022 - 2025 — McMap. All rights reserved.