AnimatedSwitcher with IndexedStack

前端 未结 3 1121
抹茶落季
抹茶落季 2021-01-05 00:35

I have to use IndexedStack to maintain the state of my widgets for my BottomNavigationBar. Now i want to use AnimatedSwitcher (or an alternative) to create an animation when

相关标签:
3条回答
  • 2021-01-05 01:30

    This is a cleaner way to use IndexedStack with animations , I created a FadeIndexedStack widget.

    https://gist.github.com/diegoveloper/1cd23e79a31d0c18a67424f0cbdfd7ad

    Usage

    body: FadeIndexedStack(  
        //this is optional
        //duration: Duration(seconds: 1),
        children: _tabs.map((t) => t.widget).toList(),  
        index: _currentIndex,  
      ),  
    
    
    0 讨论(0)
  • 2021-01-05 01:36

    Try to add key to your IndexedStack so your code will look like:

    body: AnimatedSwitcher(  
      duration: Duration(milliseconds: 200),  
      child: IndexedStack(
        key: ValueKey<int>(_currentIndex),
        children: _tabs.map((t) => t.widget).toList(),  
        index: _currentIndex,  
      ),  
    )
    

    The key is changed so AnimatedSwitcher will know that it's child is need to rebuild.

    0 讨论(0)
  • 2021-01-05 01:38

    If you need to use IndexedStack.

    You can add custom animation and trigger it on changing tabs, like that:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
      final List<Widget> myTabs = [
        Tab(text: 'one'),
        Tab(text: 'two'),
        Tab(text: 'three'),
      ];
    
      AnimationController _animationController;
      TabController _tabController;
      int _tabIndex = 0;
      Animation animation;
    
      @override
      void dispose() {
        _tabController.dispose();
        super.dispose();
      }
    
      @override
      void initState() {
        _tabController = TabController(length: 3, vsync: this);
        _animationController = AnimationController(
          vsync: this,
          value: 1.0,
          duration: Duration(milliseconds: 500),
        );
        _tabController.addListener(_handleTabSelection);
        animation = Tween(begin: 0.0, end: 1.0).animate(_animationController);
        super.initState();
      }
    
      _handleTabSelection() {
        if (!_tabController.indexIsChanging) {
          setState(() {
            _tabIndex = _tabController.index;
          });
          _animationController.reset();
          _animationController.forward();
        }
      }
    
      @override
      Widget build(BuildContext context) {
        List<Widget> _tabs = [
          MyAnimation(
            animation: animation,
            child: Text('first tab'),
          ),
          MyAnimation(
            animation: animation,
            child: Column(
              children: List.generate(20, (index) => Text('line: $index')).toList(),
            ),
          ),
          MyAnimation(
            animation: animation,
            child: Text('third tab'),
          ),
        ];
    
        return Scaffold(
          appBar: AppBar(),
          bottomNavigationBar: TabBar(
            controller: _tabController,
            labelColor: Colors.redAccent,
            isScrollable: true,
            tabs: myTabs,
          ),
          body: IndexedStack(
            children: _tabs,
            index: _tabIndex,
          ),
        );
      }
    }
    
    class MyAnimation extends AnimatedWidget {
      MyAnimation({key, animation, this.child})
          : super(
              key: key,
              listenable: animation,
            );
    
      final Widget child;
    
      @override
      Widget build(BuildContext context) {
        Animation<double> animation = listenable;
        return Opacity(
          opacity: animation.value,
          child: child,
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题