【问题标题】:how to manage tabs in flutter application如何管理颤振应用程序中的选项卡
【发布时间】:2021-07-03 05:27:40
【问题描述】:

我的应用程序中有 3 个选项卡,并且有一个日期选择器,每当我选择日期(可能是哪个选项卡)时,所有选项卡的日期选择器都是相同的,3 个选项卡中的所有数据都将根据所选日期发生变化并且为此提供了很多api。 但问题是每次我切换标签时,所有 api 都会再次点击。所以我如何管理标签,以便在我再次选择日期之前它不会在切换时点击 api

class HomePage extends StatefulWidget {
 

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

class _HomePageState extends State<HomePage> {
  SelectedDates _selectedDates = SelectedDates();
  List<DateTime> selectedDates = List();
  int _currentIndex = 0;
  List<Widget> _children = [
    FirstPage(),
    ChartPage(),
    ActionPage(),
  ];

  onTabSelected(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    final _homeProvider = Provider.of<HomeProvider>(context);
    final _chartProvider = Provider.of<ChartListingProvider>(context);
    final _actionProvider = Provider.of<ActionProvider>(context);
    showDatePickerDialog(BuildContext context) async {
      final List<DateTime> picked = await DateRagePicker.showDatePicker(
        context: context,
        initialFirstDate: DateTime.now(),
        firstDate: DateTime(2015),
        initialLastDate: (DateTime.now()).add(
          Duration(days: 7),
        ),
        lastDate: DateTime(2025),
      );
      if (picked != null && picked.length == 2 && picked != selectedDates) {
        setState(() {
          selectedDates = picked;
          var formatter = DateFormat('dd/MM/yyyy');
          _selectedDates?.fromDate = formatter.format(picked[0]);
          _selectedDates?.endDate = formatter.format(picked[1]);

             _actionProvider.setDate(_selectedDates);

          _chartProvider.setDate(_selectedDates);

          _homeProvider.setDate(_selectedDates);
         
        });
      }
    }

    return ValueListenableBuilder(
      valueListenable: Hive.box(userDetailsBox).listenable(),
      builder: (_, Box box, __) {
        String token = box.get(authTokenBoxKey);
        String id = box.get(companyIdBoxKey);
        
         _actionProvider.setTokenAndCompanyId(token, id);
         //in the above function i have provided the apis related to third tab
        _chartProvider.setTokenAndCompanyId(token, id);
        //in the above function i have provided the apis related to second tab
        __homeProvider.setTokenAndCompanyId(token, id);
         //in the above function i have provided the apis related to first tab
        
          return DefaultTabController(
            length: 3,
            initialIndex: 1,
            child: Scaffold(
              floatingActionButton: FloatingActionButton(
                onPressed: () {
                  showDatePickerDialog(context);
                },
                child: Icon(Icons.date_range),
                backgroundColor: Theme.of(context).accentColor,
              ),
              
              appBar: AppBar(title: Text("Tab Controller"), actions: <Widget>[]),
              bottomNavigationBar: BottomNavigationBar(
                onTap: onTabSelected,
                items: [
                  BottomNavigationBarItem(
                    icon: Icon(Icons.home),
                    title: Text("Home"),
                  ),
                  BottomNavigationBarItem(
                    icon: Icon(Icons.list),
                    title: Text("Chart"),
                  ),
                  BottomNavigationBarItem(
                    icon: Icon(Icons.redo),
                    title: Text("Action"),
                  ),
                ],
                currentIndex: _currentIndex,
              ),
              body: _children[_currentIndex],
            ),
          );
       
      },
    );
  }
}
 

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    这是因为 setstate 强制您的整个小部件重建。

    onTabSelected(int index) {
        setState(() {
          _currentIndex = index;
        });
      }
    

    对于这种情况,您可以使用提供程序或其他状态管理库,例如 RXdartRiverpodProviders 或其他任何东西。

    这些状态管理库使您可以访问状态并通知更改,而无需重建整个树。您可以通过谷歌搜索来探索很多概念。

    实施

    这是一个使用 Providers 包的示例实现: NavigationNotifier:

    import 'package:flutter/material.dart';
    
    class NavigationNotifier with ChangeNotifier {
      int _currentIndex = 0;
    
      get currentIndex => _currentIndex;
    
      set currentIndex(int index) {
        _currentIndex = index;
        notifyListeners();
      }
    }
    

    你的主文件/主页,随便什么:

    class Home extends StatelessWidget {
      final List<Widget> _children = [Screen1(), Screen2()];
    
      @override
      Widget build(BuildContext context) {
        var provider = Provider.of<NavigationNotifier>(context);
    ...
    bottomNavigationBar: BottomNavigationBar(
                    onTap: (index) {
                      provider.currentIndex = index;
                    },
                    currentIndex: provider.currentIndex,
                    showSelectedLabels: true,
                    showUnselectedLabels: true,
                    items: [
                      BottomNavigationBarItem(
                          icon: new Icon(Icons.home), label: 'home'),
                      BottomNavigationBarItem(
                          icon: new Icon(Icons.supervised_user_circle_outlined),
                          label: 'Profile')
                    ],
                  ),
                  body: _children[provider.currentIndex]),
    

    【讨论】:

    • 感谢 Marcel Dz 先生的回复。明白了你的意思,并用你提到的提供者进行了暗示,但问题仍然存在,索引更改它再次从 build() 重建。请帮助解决这个问题
    • 你删除了所有的 setstate 吗?
    • 是的,我删除了它,但它没有用,接下来尝试在正文中使用索引堆栈实现:IndexedStack(index:_provider.currentIndex,children:[FirstPage(),ChartPage(), ActionPage(), ]) 也不起作用
    • 我关注了这个stackoverflow.com/a/55512883/12953031,但没有成功
    猜你喜欢
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多