简体   繁体   中英

how to manage tabs in flutter application

I have 3 tabs in my application and there is a date picker which is same for all the tabs whenever i choose the date (from which ever tab it may be)all the data in 3 tabs will change corresponding to the choosen date and so many apis have been provided to this. But the problem is every time whenever i switch the tab all the apis are hiting again.so how can i manage the tabs so that it will not hit the apis on switching until i choose the date again

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

It's because of the setstate which force your whole widget to rebuild.

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

For this case you can use providers or other State Management librarys out there like RXdart , Riverpod , Providers or anything else.

These state management librarys give you access to the states and notifies about changes without rebuilding the whole tree. There are a lot of concepts out there you can explore by googling.

Implementation

This is an example implementation using Providers package: NavigationNotifier:

import 'package:flutter/material.dart';

class NavigationNotifier with ChangeNotifier {
  int _currentIndex = 0;

  get currentIndex => _currentIndex;

  set currentIndex(int index) {
    _currentIndex = index;
    notifyListeners();
  }
}

Your main file/ home, whatever:

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

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