Home > Blockchain >  Flutter animate children in list view dynamically
Flutter animate children in list view dynamically

Time:01-19

I am trying to implement a design that looks like this:

example

In the example the currentItem in the middle is of size 19 and its opacity is at 100%. The 2nd item below/above it is of size 13 with an opacity of 50% and the third items are of size 9 and with anopacity of 25%.

How could I implement something like this with Flutter? I've tried multiple things, for example ListWheelScrollView but I couldn't get the desired design.

One more requirement: The currentItem should be tappable.

Any idea how I could get this done?

CodePudding user response:

A solution could be to use a CupertinoPicker to achieve the design you're looking for.

For example, using a StatefulWidget to update and retrieve the currentIndex :

  static const double _containerHeight = 500;
  int currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: _containerHeight,
      child: CupertinoPicker.builder(
        itemExtent: _containerHeight / 3,
        diameterRatio: 20,
        useMagnifier: false,
        selectionOverlay: null,
        onSelectedItemChanged: (value) => setState(() => currentIndex = value),
        itemBuilder: (context, index) {
          return Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              AnimatedDefaultTextStyle(
                duration: const Duration(milliseconds: 200),
                style: TextStyle(fontSize: getFontSizeFromIndex(index)),
                child: Text(
                  'Das ist ein Text',
                  style: TextStyle(
                      color:
                          Colors.white.withOpacity(getOpacityFromIndex(index))),
                ),
              ),
            ],
          );
        },
      ),
    );
  }

  double getFontSizeFromIndex(int index) => index == currentIndex
      ? 19
      : index == currentIndex - 1 || index == currentIndex   1
          ? 13
          : 9;

  double getOpacityFromIndex(int index) => index == currentIndex
      ? 1
      : index == currentIndex - 1 || index == currentIndex   1
          ? .5
          : .25;

To go further, you should considerate :

  • debouncing the onSelectedItemChanged in order to prevent abusive rebuilds ;
  • using a custom ScrollController and do some linear interpolations in order to make the animation smoother.

Here is the result :

enter image description here

  • Related