Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 362
molundb Avatar asked Oct 19 '18 09:10

molundb


People also ask

How do you change the tab on a button click in flutter?

You need to get the TabBar controller and call its animateTo() method from the button onPressed() handle. Save this answer.

How do you use AnimatedBuilder in flutter?

AnimatedBuilder is useful for more complex widgets that wish to include an animation as part of a larger build function. To use AnimatedBuilder, simply construct the widget and pass it a builder function. For simple cases without additional state, consider using AnimatedWidget.

How do you use TabController in flutter?

The selected tab's index can be changed with animateTo. A stateful widget that builds a TabBar or a TabBarView can create a TabController and share it directly. When the TabBar and TabBarView don't have a convenient stateful ancestor, a TabController can be shared by providing a DefaultTabController inherited widget.


Video Answer


4 Answers

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

enter image description here

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(),
      ),
    );
  }
}
like image 157
Kherel Avatar answered Oct 11 '22 23:10

Kherel


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

like image 24
Gaspard Merten Avatar answered Oct 11 '22 23:10

Gaspard Merten


Screenshot (Null safe):

enter image description here


Code:

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')),
        ],
      ),
    );
  }
}
like image 2
CopsOnRoad Avatar answered Oct 11 '22 23:10

CopsOnRoad


Disable animation between flutter tabs by setting animation duration to zero like this

    tabController = TabController(
    animationDuration: Duration.zero,
    length: 4, vsync: this, initialIndex: 0);

Thank me later.

like image 1
MUHINDO Avatar answered Oct 11 '22 23:10

MUHINDO