Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refresh a listview outside of a widget in Flutter?

Tags:

flutter

dart

I have a Flutter application which comprises of a scaffold with a slider and a tabview.

The tabview comprises of a List which is show on each tab as seen in the picture below.

  List<Widget> widgetList = <Widget>[
    Post(),
    Feed(),
    Location(),
    HomePage(),
    Feed(),
  ];

Now I would like to refresh the current tab on screen when the slider is moved. However, since the classes are private i.e. _HomePageState, I do not know how to access the refreshList() method as shown in the snippet below.

homepage.dart:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var list;
  var random;

  var refreshKey = GlobalKey<RefreshIndicatorState>();

  @override
  void initState() {
    super.initState();
    random = Random();
    refreshList();
  }

  Future<Null> refreshList() async {
    refreshKey.currentState?.show(atTop: false);
    await Future.delayed(Duration(seconds: 2));

    setState(() {
      list = List.generate(random.nextInt(10), (i) => "Item $i");
    });

    return null;
  }
}

The slider is not baked into each listview Widget i.e. homepage.dart as the slider values is applicable to each individual tab. How can I refresh the inner listview widget when the outer widget with the slider is moved?

enter image description here

like image 490
Carrein Avatar asked Jul 21 '18 19:07

Carrein


People also ask

How do I move data from one widget to another widget in flutter?

Steps to Pass Data to Stateful Widget in Flutter To pass data to stateful widget, first of all, create two pages. Now from the first page open the second page and pass the data. Inside the second page, access the variable using the widget. For example widget.

How do you refresh a list after deleting in flutter?

Flutter should automatically update to reflect changes to datasources. However, this is only applied after calling: setState((){ }); So that should be run after you delete the item from the list.


1 Answers

There are different ways to deal with this:

  1. You could pass down the PageController and the page index to your page widgets. In your page widgets can then listen to the changes (pageController.addListener(...)) and compare the currently centered page with their page index.

  2. Create one ChangeNotifier for every page that you want to refresh:

    final postRefresh = ChangeNotifier();
    final feedRefresh = ChangeNotifier();
    ...
    
    // build method of parent:
    List<Widget> widgetList = <Widget>[
      Post(refresh: postRefresh),
      Feed(refresh: feedRefresh),
      ...
    ];
    
    // initState method of parent:
    pageController.addListener(() {
      final roundedPage = pageController.page.round();
      if(roundedPage == 0) {
        postRefresh.notifyListeners();
      }
      else if(roundedPage == 1) {
        feedRefresh.notifyListeners();
      }
      // ...
    })
    
  3. You could also give your page widgets a global key (for that, their State classes must be public):

    // class body of parent:
    final postPageKey = GlobalKey<PostPageState>();
    final feedPageKey = GlobalKey<FeedPageState>();
    
    // build method of parent:
    List<Widget> widgetList = <Widget>[
      Post(key: postPageKey),
      Feed(key: feedPageKey),
      ...
    ];
    
    // initState method of parent:
    pageController.addListener(() {
      final roundedPage = pageController.page.round();
      if(roundedPage == 0) {
        postPageKey.currentState?.refresh();
      }
      else if(roundedPage == 1) {
       feedPageKey.currentState?.refresh();
      }
      // ...
    })
    
like image 61
boformer Avatar answered Oct 15 '22 12:10

boformer