简体   繁体   中英

How to show Circular Progress Indicator until value is loaded?

I have a Widget which on first click shows error page that value that I am trying to reach is null... When I open that Widget second time then it works because on first click the value is loaded and screen is showed properly. How can I achieve that user sees Circular Progress Indicator instead of error page until value is loaded?

This is the Widget:

  Widget build(BuildContext context){
    var user = Provider.of<UserRepository>(context);
    user.cacheGet();
    return Scaffold(
      appBar: AppBar(
        title: Text("Last Conversation"),
      ),
      body: user.conversationID.values == null
          ? Center(
              child: CircularProgressIndicator(),
            )
          : Container(
              child: _myListView(context, user.conversationID.values),
            ),
    );
  }

This shows error because user.conversationID.values is null . It is loaded through cacheGet( ) function which has type Future <bool> ... So if I go back and open same screen (widget) again then that value is loaded and no error is shown. I tried to use ternary operator but in this case it does not work.

EDIT

This is cacheGet function.

  Future<bool> cacheGet() async {
    String token = await getToken();
    var body = jsonEncode({"token": token, "userID": this.firebaseUser.uid});
    var res = await http.post((baseUrl + "/cacheGet"), body: body, headers: {
      "Accept": "application/json",
      "content-type": "application/json"
    });

    if (res.statusCode == 200) {
      this.conversationID = Conversations.fromJson(json.decode(res.body));
      return true;
    }

    return false;
  }

Simply wrap your widget with future builder. Here is an sample code:

FutureBuilder<bool>(
        future: user.cacheGet(),
        builder: (BuildContext context, AsyncSnapshot snapshot){
          if(snapshot.hasData){
            return user.conversationID.values == null
                ? Center(
              child: CircularProgressIndicator(),
            )
                : Container(
              child: _myListView(context, user.conversationID.values),
            );
          }else{
            return Container();
          }
        },
      )

Likely a routine like user.cacheGet(); should not be done inside build() , but probably initState() would be a better place for it.

I recommend looking at FutureBuilder (or StreamBuilder ). Think about how your value is likely a Future , then your build routine will use FutureBuilder that will show the CircularProgressIndicator() while it is waiting for data, and then whatever else you want once you have the data (or the third case is that there was an error fetching the data). The future should be initialized in initState() .

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