I'm doing a flutter app with Cupertino, I'm trying to figure out how to recall method initState each time that I navigate to this tab (MapPage).

This method initState() calls other mehtod "initPlatformState()" who asks for the permission location and makes a request to an API, with this result I build a marker per each object's result and show them on the map.

Here is the code of the map page.

https://gist.github.com/GreyHat147/3ea92f4e962218893b84af667452b087

This is the ui.

enter image description here

1 Answers

1
android On Best Solutions

For CupertinoTabBar you can do as below where create instance of state class and the without creating it again called it only on tap:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

MyHome myHome = new MyHome();
MyNearMe myNearMe = new MyNearMe();
MyMap myMap = new MyMap();
MyNotifications myNotifications = new MyNotifications();
MyWallet myWallet = new MyWallet();

MyHomeState myHomeState = MyHomeState();
MyNearMeState myNearMeState = MyNearMeState();
MyMapState myMapState = MyMapState();
MyNotificationsState myNotificationsState = MyNotificationsState();
MyWalletState myWalletState = MyWalletState();
int indexPrevValue = 0;

class TabBarPage extends StatefulWidget {
  TabBarPage({Key key, this.userId})
      : super(key: key);

  final String userId;

  @override
  _TabBarPage createState() => new _TabBarPage();
}


class _TabBarPage extends State<TabBarPage> {
  _TabBarPage({Key key, this.userId});

  final String userId;

  void _onTap(int value) {
    print('Value => $value');
    if(value == 0){
      myHomeState.initState();
    }
    else if(value == 1){
      myNearMeState.initState();
    }
    else if(value == 2){
      myMapState.initState();
    }
    else if(value == 3){
      myNotificationsState.initState();
    }
    else if(value == 4){
      myWalletState.initState();
    }
    indexPrevValue = value;
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        onTap: _onTap,
        activeColor: new Color.fromRGBO(148, 3, 123, 1.0),
        items: <BottomNavigationBarItem>[
          new BottomNavigationBarItem(
            title: new Text('Home'),
            icon: new Icon(
              Icons.home,
              size: 22,
            ),
          ),
          new BottomNavigationBarItem(
            title: new Text('Near me'),
            icon: new Icon(
              Icons.location_on,
              size: 22,
            ),
          ),
          new BottomNavigationBarItem(
              icon: new Icon(
                Icons.map,
                size: 22,
              ),
              title: new Text('Map')
          ),
          new BottomNavigationBarItem(
              title: new Text('Notifications'),
              icon: new Icon(
                Icons.notifications,
                size: 22,
              )
          ),
          new BottomNavigationBarItem(
              title: new Text('Wallet'),
              icon: new Icon(
                Icons.account_balance_wallet,
                size: 22,
              )
          ),
        ],
      ),


      tabBuilder: (BuildContext context, int index) {
        switch (index) {
          case 0:
            return CupertinoTabView(
              builder: (BuildContext context) {
                if(myHomeState == null){
                  myHomeState = myHome.createState();
                }
                return myHome.createState().build(context);
              },
            );
            break;

          case 1:
            return CupertinoTabView(
              builder: (BuildContext context) {
                if(myNearMeState == null){
                  myNearMeState = myNearMe.createState();
                }
                return myNearMe.createState().build(context);
              },
            );
            break;

          case 2:
            return CupertinoTabView(
              builder: (BuildContext context) {
                if(myMapState == null){
                  myMapState = myMap.createState();
                }
                return myMap.createState().build(context);
              },
            );
            break;

          case 3:
            return CupertinoTabView(
              builder: (BuildContext context) {
                if(myNotificationsState == null){
                  myNotificationsState = myNotifications.createState();
                }
                return myNotifications.createState().build(context);
              },
            );
            break;

          case 4:
            return CupertinoTabView(
              builder: (BuildContext context) {
                if(myWalletState == null){
                  myWalletState = myWallet.createState();
                }
                return myWallet.createState().build(context);
              },
            );
            break;

        }
      },
    );
  }
}



class MyHome extends StatefulWidget {
  @override
  MyHomeState createState() => new MyHomeState();
}

class MyHomeState extends State<MyHome> {

  @override
  void initState() {
    super.initState();
    print('MyHomeState initState() called');
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("test stream"),
        ),
        body: Container(
          padding: EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Text('HOME 1')
            ],
          ),
        ));
  }
}





class MyNearMe extends StatefulWidget {
  @override
  MyNearMeState createState() => new MyNearMeState();
}

class MyNearMeState extends State<MyNearMe> {

  @override
  void initState() {
    super.initState();
    print('MyNearMeState initState() called');
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("MyNearMe"),
        ),
        body: Container(
          padding: EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Text('My Near Me')
            ],
          ),
        ));
  }
}




class MyMap extends StatefulWidget {
  @override
  MyMapState createState() => new MyMapState();
}

class MyMapState extends State<MyMap> {

  @override
  void initState() {
    super.initState();
    print('MyMapState initState() called');
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("MyMap"),
        ),
        body: Container(
          padding: EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Text('My Map')
            ],
          ),
        ));
  }
}





class MyNotifications extends StatefulWidget {
  @override
  MyNotificationsState createState() => new MyNotificationsState();
}

class MyNotificationsState extends State<MyNotifications> {

  @override
  void initState() {
    super.initState();
    print('MyNotificationsState initState() called');
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("MyNotifications"),
        ),
        body: Container(
          padding: EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Text('My Notifications')
            ],
          ),
        ));
  }
}





class MyWallet extends StatefulWidget {
  @override
  MyWalletState createState() => new MyWalletState();
}

class MyWalletState extends State<MyWallet> {

  @override
  void initState() {
    super.initState();
    print('MyWalletState initState() called');
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("MyWallet"),
        ),
        body: Container(
          padding: EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              Text('My Wallet')
            ],
          ),
        ));
  }
}

If you want to use another bottom navigation bar instead of cupertino then you can use as below:

I have created a sample example for you where initState() will call every time on tab change whether its same tab or different tab:

First of all import "bmnav: ^0.3.4" library in pubspec.yaml and then copy and paste below code:

import 'package:flutter/material.dart';
import 'package:bmnav/bmnav.dart' as bmnav;

Widget currentScreen = null;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    currentScreen = MyHomeMapSample();
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();

}



class _MyHomePageState extends State<MyHomePage> {

  @override
  void initState(){
    super.initState();
  }
  int currentTab = 0;
  int prevTab = 0;

  final PageStorageBucket bucket = PageStorageBucket();

  @override
  Widget build(BuildContext ctx) {
    debugPrint('currentTab: $currentTab');
    return Scaffold(

      body: PageStorage(child: currentScreen, bucket: bucket),
      bottomNavigationBar: SizedBox(height: 58,
        child: bmnav.BottomNav(
          index: currentTab,
          onTap: (i) {
            setState(() {
              currentTab = i;
              currentScreen = getWidget(context, i);
              if(prevTab==currentTab){
                if(i==0){
                  MyHomeMapSample map = currentScreen as MyHomeMapSample;
                  map.createState().initState();
                }else if(i==1){
                  MyHomeWorkouts map = currentScreen as MyHomeWorkouts;
                  map.createState().initState();
                }
                else if(i==2){
                  MyHomeAccount map = currentScreen as MyHomeAccount;
                  map.createState().initState();
                }
              }
              prevTab = currentTab;
            });
          },
          labelStyle: bmnav.LabelStyle(visible: true),
          items: [
            bmnav.BottomNavItem(Icons.map, label: 'Map'),
            bmnav.BottomNavItem(Icons.cast, label: 'Workouts'),
            bmnav.BottomNavItem(Icons.textsms, label: 'Account'),
          ],
        ),
      ),
      resizeToAvoidBottomPadding: true,
    );
  }

  Widget getWidget(BuildContext context, int i){
    if(i==0){
      return MyHomeMapSample();
    }

    else if(i==1){
      return MyHomeWorkouts();

    }else if(i==2){
      return MyHomeAccount();
    }
  }

}



class MyHomeMapSample extends StatefulWidget {
  MyHomeMapSample({Key key}) : super(key: key);
  @override
  MapSample createState() => MapSample();
}

class MapSample extends State<MyHomeMapSample> {
  var myVariable = 0;

  @override
  void initState(){
    super.initState();
    debugPrint('current: MapSample: initState() called!');
  }

  @override
  Widget build(BuildContext context) {
    myVariable = myVariable + 1;
    return Scaffold(
      appBar: AppBar(
        title: Text('MapSample'),
      ),
      body: Center(
        child: Text('MapSample details + $myVariable'),
      ),
      resizeToAvoidBottomPadding: true,
    );
  }

}



class MyHomeWorkouts extends StatefulWidget {
  MyHomeWorkouts({Key key}) : super(key: key);
  @override
  Workouts createState() => Workouts();
}

class Workouts extends State<MyHomeWorkouts> {
  var myVariable = 0;

  @override
  void initState(){
    super.initState();
    debugPrint('current: Workouts: initState() called!');
  }

  @override
  Widget build(BuildContext context) {
    myVariable = myVariable + 1;
    return Scaffold(
      appBar: AppBar(
        title: Text('Workouts'),
      ),
      body: Center(
        child: Text('Workouts details + $myVariable'),
      ),
      resizeToAvoidBottomPadding: true,
    );
  }

}




class MyHomeAccount extends StatefulWidget {
  MyHomeAccount({Key key}) : super(key: key);
  @override
  Account createState() => Account();
}

class Account extends State<MyHomeAccount> {
  var myVariable = 0;

  @override
  void initState(){
    super.initState();
    debugPrint('current: Account: initState() called!');
  }

  @override
  Widget build(BuildContext context) {
    myVariable = myVariable + 1;
    return Scaffold(
      appBar: AppBar(
        title: Text('Account'),
      ),
      body: Center(
        child: Text('Account details + $myVariable'),
      ),
      resizeToAvoidBottomPadding: true,
    );
  }

}