Flutter - изменение анимации TabBarView

Я реализовал базовую панель TabBar и TabBarView с помощью DefaultTabController, см. Код ниже.

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),
        )
      ],
    );
  }
}

Работает отлично! Теперь я хочу изменить анимацию между двумя вкладками по сравнению с анимацией по умолчанию. Но я не могу найти простого способа сделать это.

После небольшого исследования мне кажется, что мне нужно использовать настраиваемый TabController и каким-то образом использовать его animateTo. Мне кажется, что просто изменить анимацию - это довольно серьезное изменение. Что меня интересует, правильно ли это или мне не хватает более простого способа просто изменить анимацию по умолчанию между представлениями вкладок?

Если бы кто-то мог дать мне хорошие ресурсы, чтобы указать мне правильное направление, я был бы очень признателен.


person molundb    schedule 19.10.2018    source источник
comment
Если вы хотите, чтобы анимация между вкладками менялась, посмотрите: github.com/therezacuet/Motion-Tab- Бар   -  person Paresh Mangukiya    schedule 19.09.2020


Ответы (2)


Это несложно, просто используйте TabController (для этого вам нужно использовать SingleTickerProviderStateMixin) и 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(),
      ),
    );
  }
}
person Kherel    schedule 19.08.2019
comment
Что означает этот двойной массив в Transform.rotate () внутри функции _tabBarView? Это похоже на многомерный массив? - person Sarvesh Dalvi; 21.03.2021
comment
это не двойной массив. В первых скобках находится список вкладок, а во вторых скобках - индекс текущей вкладки. - person Kherel; 22.03.2021
comment
Если вы хотите вообще не иметь анимации, будет ли этот подход полезен? - person Iván Yoed; 19.05.2021
comment
тогда вам не нужен tabview, просто добавьте все виджеты вкладок в список и сохраните tabController.index в состоянии. для этого вам нужен addListener для tabController и сохранение индекса при indexIsChanging, аналогичная идея здесь stackoverflow.com/questions/52547731/, но вам не нужен индексированный стек ... - person Kherel; 19.05.2021

Не знаю, хотите ли вы полностью изменить анимацию.

Но если вам просто нужна некоторая настройка, вы пытались использовать TabController вместо DefaultTabController? Вам просто нужно передать tabController в качестве аргумента TabBar & TabBarView.

Чтобы настроить анимацию с tabController, вы должны указать Animation для tabController, а также указать кривую и продолжительность с помощью функции animateTo tabController.

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

person Gaspard Merten    schedule 04.06.2019