简体   繁体   中英

Flutter - Change the animation of TabBarView

I implemented a basic TabBar and TabBarView with a DefaultTabController, see code below.

class MyApp2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: BOTTOM_TABS,
      child: Scaffold(
        appBar: AppBar(title: const Text('Bottom App Bar')),
        body: _tabBarView(),
        bottomNavigationBar: _bottomTabBar(),
      ),
    );
  }

  _tabBarView() {
    return TabBarView(
      physics: NeverScrollableScrollPhysics(),
      children: [
        Container(
          color: Colors.blue,
        ),
        Container(
          color: Colors.orange,
        ),
        Container(
          color: Colors.lightGreen,
        ),
        Container(
          color: Colors.red,
        ),
      ],
    );
  }

  _bottomTabBar() {
    return TabBar(
      tabs: [
        Tab(
          icon: new Icon(Icons.home),
        ),
        Tab(
          icon: new Icon(Icons.public),
        ),
        Tab(
          icon: new Icon(Icons.group),
        ),
        Tab(
          icon: new Icon(Icons.person),
        )
      ],
    );
  }
}

Works great! Now what I want to do is change the animation between the two tabs from the default animation. But I can't find an easy way to do that.

After a bit of research it seems like I need to use a custom TabController and somehow use its animateTo method. To me that seems like a pretty big change just to change the animation. What I wonder is if that is the correct way or if I am missing some easier way to just change the default animation between the tabviews?

If someone could give me some good resources to point me in the right direction I'd greatly appreciate it.

This is not hard, just use TabController (to do so you need to use SingleTickerProviderStateMixin ) and AnimatedBuilder.

在此处输入图片说明

class MyApp2 extends StatefulWidget {
  @override
  _MyApp2State createState() => _MyApp2State();
}

class _MyApp2State extends State<MyApp2> with SingleTickerProviderStateMixin {
  TabController _tabController;

  @override
  void initState() {
    _tabController = TabController(length: 4, vsync: this);
    super.initState();
  }

  _tabBarView() {
    return AnimatedBuilder(
      animation: _tabController.animation,
      builder: (BuildContext context, snapshot) {
        return Transform.rotate(
          angle: _tabController.animation.value * pi,
          child: [
            Container(
              color: Colors.blue,
            ),
            Container(
              color: Colors.orange,
            ),
            Container(
              color: Colors.lightGreen,
            ),
            Container(
              color: Colors.red,
            ),
          ][_tabController.animation.value.round()],
        );
      },
    );
  }

  _bottomTabBar() {
    return TabBar(
      controller: _tabController,
      labelColor: Colors.black,
      tabs: [
        Tab(
          icon: new Icon(Icons.home),
        ),
        Tab(
          icon: new Icon(Icons.public),
        ),
        Tab(
          icon: new Icon(Icons.group),
        ),
        Tab(
          icon: new Icon(Icons.person),
        )
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 4,
      child: Scaffold(
        appBar: AppBar(title: const Text('Bottom App Bar')),
        body: _tabBarView(),
        bottomNavigationBar: _bottomTabBar(),
      ),
    );
  }
}

I don't know if you want to completely change the animation.

But if you just need some customization, did you try to use a TabController instead of a DefaultTabController ? You just need to pass the tabController as an arg to the TabBar & TabBarView .

To customize the animation with the tabController , you should specify an Animation for the tabController and also specify the curve and duration with the animateTo function of the tabController .

https://api.flutter.dev/flutter/material/TabController/animateTo.html https://api.flutter.dev/flutter/material/TabController-class.html

Screenshot (Null safe):

在此处输入图片说明


If you want fine-grained control, you can make use of the AnimationController .

class _MyPageState extends State<MyPage> with TickerProviderStateMixin {
  late final TabController _tabController;
  late final AnimationController _controller;

  @override
  void initState() {
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 400),
      value: 1,
    );

    _tabController = TabController(
      length: 3,
      vsync: this,
    )..addListener(() {
        if (_tabController.indexIsChanging) {
          setState(() => _controller.forward(from: 0.5));
        }
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ScaleTransition(
        scale: _controller,
        child: [
          Container(color: Colors.red),
          Container(color: Colors.green),
          Container(color: Colors.blue),
        ][_tabController.index],
      ),
      bottomNavigationBar: TabBar(
        controller: _tabController,
        tabs: [
          Tab(child: Text('Red')),
          Tab(child: Text('Green')),
          Tab(child: Text('Blue')),
        ],
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM