Search code examples
androidlistviewdartscrollableflutter

One ListView isn't scrollable in AnimatedCrossFade


I'm new in flutter development and I have a problem: I create new AnimatedCrossFade and add two different ListView to first and second child, but always one child ListView scrollable. How can I do scrollable ListView in first and second child?

(Same situation with simple GridView.)


Solution

  • This looks like a bug in AnimatedCrossFade. I filed an issue.

    You can work around it by not using AnimatedCrossFade and building your own animation using FadeTransition. Source code is below. Click the play button, it will start like this

    blue

    and end like this:

    red

    You can fade back and forth by clicking the button again. Both lists are scrollable and it remembers your scroll position.

    import 'package:flutter/widgets.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatefulWidget {
      createState() => new MyAppState();
    }
    
    class MyAppState extends State<MyApp> with TickerProviderStateMixin {
      AnimationController _controller;
      Key _key1 = new GlobalKey();
      Key _key2 = new GlobalKey();
    
      @override
      void initState() {
        _controller = new AnimationController(
          duration: const Duration(milliseconds: 700),
          vsync: this,
        );
      }
    
      Widget _buildList(Key key, Color color, double opacity) {
        return new Opacity(
          opacity: opacity,
          child: new Container(
            // Keep the hidden ListView around to maintain its scroll position
            // but set its height to 0.0 so it can't interfere with touches
            height: opacity == 0.0 ? 0.0 : null,
            decoration: new BoxDecoration(color: color),
            child: new ListView(
              key: new GlobalObjectKey(color),
              children: new List.generate(
                100,
                (index) => new Text('Item $index'),
              ),
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          home: new Scaffold(
            floatingActionButton: new FloatingActionButton(
              child: new Icon(Icons.play_arrow),
              onPressed: () {
                if (_controller.status == AnimationStatus.dismissed ||
                  _controller.status == AnimationStatus.reverse) {
                  _controller.forward();
                } else {
                  _controller.reverse();
                }
              },
            ),
            body: new Center(
              child: new Container(
                width: 100.0,
                height: 100.0,
                child: new AnimatedBuilder(
                animation: _controller,
                builder: (BuildContext context, Widget child) {
                  return new Stack(
                    children: [
                      _buildList(_key1, Colors.red[200], _controller.value),
                      _buildList(_key2, Colors.blue[200], 1.0 - _controller.value),
                    ],
                  );
                }
              ),
            ),
            ),
          ),
        );
      }
    }
    }