How to show RefreshIndicator while waiting for data from backend API?

So I have this Notifications screen that displays notifications to the user. When navigating to this screen, it will be blank as notifications are being loaded in real time from the API.

Here's some code to illustrate the problem:

class _MyItemsPageState extends State<MyItemsPage> {
  final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
      new GlobalKey<RefreshIndicatorState>();
  List<MyItem> _items = [];

  @override
  void initState() {
    super.initState();

    // Nothing is displaying on screen initially, since the items are loaded from API on startup.
    // Preferably in this state, the refresh indicator would be shown while the items load.
    // It not currently possible in this place, since it seems that the Widget hasn't been built yet.

    _refreshIndicatorKey.currentState.show(); // currentState null at this time, so the app crashes.
    _loadItems();
  }

  // (unrelated code removed)

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new RefreshIndicator(
        key: _refreshIndicatorKey,
        onRefresh: _loadItems,
        child: new ListView(
          padding: new EdgeInsets.symmetric(vertical: 8.0),
          children: _buildItemWidgets(),
        ),
      ),
    );
  }
}

      

The problem is that _refreshIndicator.currentState is null when initState () is called , since the widget has not been created yet.

What would be the place to call show () in RefreshIndicator in this case?

+3


source to share


1 answer


As it turns out, setting _refreshIndicator.currentState.show()

inside my function _loadItems()

did the trick. So something like:

Future _loadItems() async { 
    _refreshIndicatorKey.currentState?.show(); 
    var items = await getItems();

    setState(() { 
        _items = items; 
    });
}

      



Then I called the function _loadItems()

as usual in the method initState()

, but removed the line _refreshIndicatorKey.currentState.show()

from there.

I think this only works because of some possible race condition due to the nature of the loadItems function async

and it feels like there must be some other solution related to the lifecycle of the widget state.

+3


source







All Articles