0

I need help calling a method of another class in a pageview. I have an app which has a pageview consisting of two classes, Page 1 and Page 2 respectively. Both of them are stateful widgets.

I am trying to call a method from Page2 from Page1, but it is difficult for me as both of them do not have a child/parent relationship so I could not use a callback function. In fact, both of them are a child of another parent class (MainParent). I tried using globalkey but i received currentState is null error.

Your help is greatly appreciated. Thanks!

class MainParent extends StatefulWidget{
   @override
   MainParentState createState() => MainParentSate();
}

class MainParentState extends State<MainParent> {

  PageController pageController;

  @override
  initState(){
    pageController = new PageController(
  }

  List<Widget> _showPageList(AppModel appModel){
     List<Widget> pageList = new List();
     pageList.add(Page1(/*some named parameters pass here*/));
     pageList.add(Page2(/*some named parameters pass here*/));
     return pageList;
  }

   @override
   Widget build(BuildContext context) {
     return Scaffold(
        body: PageView(
              physics: new NeverScrollableScrollPhysics(),
              controller: pageController,
              onPageChanged: _onPageChanged,
              children: _showPageList(),
        )
     );

   }
}

Page 1 class

class Page1 extends StatefulWidget{
   @override
   Page1State createState() => Page1State();
}

class Page1State extends State<Page1> {

  _callPage2Function(){
     //animate to page 2 and mount it
     MainParent.of(context).pageController.animateToPage(
      1,
      duration: const Duration(milliseconds: 700),
      curve: Curves.fastLinearToSlowEaseIn);

     //this doesn't work
     Page2State page2state = new Page2State();
     page2state.refreshList();

     //creating a global key doesnt work as well, gets currentstate is null
     GlobalKey<Page2State> page2Key = new GlobalKey<Page2State>();
     page2Key.currentState.refreshList();
  }

   @override
   Widget build(BuildContext context) {
     return Scaffold(
        body: Container(
           child: GestureDetector(
             onTap: () => _callPage2Function()
           )
        )
     );

   }
}

Page 2 class

class Page2 extends StatefulWidget{
   @override
   Page2State createState() => Page2State();
}

class Page2State extends State<Page2> {

  refreshList(){
   //this function refreshes the list
  }

   @override
   Widget build(BuildContext context) {
     return Scaffold(
        body: Container(
           child: ListView.builder(
             //some child widgets here
           )
        )
     );

   }
}

Edit: Edited my code. Turns out I have to navigate to page2 tab first, because when I am in page 1, page 2 is not mounted to the screen. So i added a pageController and navigate to page2 first.

fadhli-sulaimi
  • 686
  • 12
  • 17

2 Answers2

0

The error in your code is that you are not injecting the key in you Page2 instance when using it, thats why the currentState in null. Usually when i want to achieve this, i use the key attribute like so

class Page2 extends StatefulWidget {
  static final GlobalKey<Page2State> staticGlobalKey =
      new GlobalKey<Page2State>();

  Page2() : super(key: Page2.currentStateKey); // Key injection
  @override
  Page2State createState() => Page2State();
}

class Page2State extends State<Page2> {
  refreshList() {

  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
            child: ListView.builder(
                //some child widgets here
                )));
  }
}

then to call the refreshList() from anywhere in your app just do

Page2.staticGlobalKey.currentState.refreshList();

You could work around and use another approach instead of static key, but this should be a working solution.

Slah Layouni
  • 650
  • 3
  • 9
  • Sorry, if i understand correctly, the currentStateKey in the named parameters here is not staticGlobalKey? So in my main parent class, I have to pass a unique key to page2? – fadhli-sulaimi Jan 21 '20 at 23:29
0

In PageView, Only one page is mounted(or active) at a time.

Here when you call page2Key.currentState.refreshList(); from Page1, the Page2 is currently unmounted(or deactive). So the state itself is null.

So you cannot do setState of another page.

Crazy Lazy Cat
  • 13,595
  • 4
  • 30
  • 54
  • I see, thanks! So if i understand correctly, I have to make sure that page 2 is mounted first, before calling any functions/static variables from that class. – fadhli-sulaimi Jan 21 '20 at 23:22