Использование Provider с TickerProviderStateMixin: где я могу инициализировать свой контроллер? - PullRequest
0 голосов
/ 01 августа 2020

Я просто играю с Flutter, и у меня возникла небольшая проблема -> вот мое репо: https://github.com/LuckyRon88/FlutterWebCV

Я использую https://pub.dev/packages/motion_tab_bar/example, чтобы создать нижнюю панель навигации в качестве дочерних элементов стека. Я буду использовать эту нижнюю панель навигации на нескольких страницах, чтобы изменить виджет на экране, поэтому я реорганизовал свой код, чтобы получить BottomNavigation.dart.

Я использую поставщика в качестве своего решения для управления состоянием.

Это TabBar https://github.com/LuckyRon88/FlutterWebCV/blob/master/lib/Components/TestTab.dart

, который я хочу использовать на https://github.com/LuckyRon88/FlutterWebCV/blob/master/lib/Screens/Education.dart, но мне нужно иметь доступ к eduTabController (из TestTab.dart ) из Education.dart, чтобы изменить некоторую информацию на этой самой странице.

У меня уже есть модель провайдера https://github.com/LuckyRon88/FlutterWebCV/blob/master/lib/ProviderPack/PageController.dart, но я не уверен, как передать Провайдеру контроль над моим eduTabController, поскольку Я не могу инициализировать его нигде, кроме самого TestTab.dart.

1 Ответ

0 голосов
/ 01 августа 2020

Поскольку controller требуется в MotionTabView, а не в MotionTabBar, переместите _eduTabController в Education класс. Теперь определите функцию, которая требуется при выборе вкладки, то есть onTabItemSelected в классе Education, и передайте ее в качестве аргумента в TestTab.

Таким образом вы можете избежать наличия _eduTabController в TestTab и используйте его в MotionTabView, которые существуют в Education.

Вот примерная реализация:

// convert Education to StatefulWidget
class Education extends StatefulWidget {

  @override
  _EducationState createState() => _EducationState();
}

// Requires SingleTickerProviderStateMixin
class _EducationState extends State<Education> with SingleTickerProviderStateMixin {
  final MotionTabController _eduTabController; // have your controller here

  @override
  void initState() {
    super.initState();
    // initialize controller
    _eduTabController = MotionTabController(initialIndex: 1, vsync: this);
  }

  @override
  void dispose() {
    super.dispose();
    // dispose controller
    _eduTabController?.dispose();
  }

  // Extract your function from TestTab
  void onTabItemSelected(int value) {
    setState(() {
      _eduTabController.index = value;
    });
  },
  
  @override
  Widget build(BuildContext context) {
    //...

         Align(
           alignment: Alignment.bottomCenter,
           child: TestTab(
             // don't pass the controller
             onTabItemSelected: onTabItemSelected, // pass the function instead
           ), 
         ),

         MotionTabBarView(
           controller: _eduTabController,
           // ...
         ),

    //...
  }

}
// This should be a StatelessWidget (because it has no state)
// Change to StatefulWidget if your requirements change
class TestTab extends StatefulWidget {
  final Function onTabItemSelected;

  TestTab({this.onTabItemSelected}); // receive your function here

  @override
  Widget build(BuildContext context) {
    return MotionTabBar(
      // ...

      onTabItemSelected: onTabItemSelected, // use the function here

      // ...
    );
  }
}
...