skip to Main Content

I would like to display a custom loading image right after a page loads, like the example in the first block of code below.

The loading screen should be visible until I get a response from async HTTP request, after which I want to replace / rebuild the entire body with a different widget and pass a variable from the getData() to the newly built body.

Please, don’t suggest to use the CircularProgressIndicator – I want to use a custom loading image.

The body after page load:

Widget build(BuildContext context) {
    return new Scaffold(
      body: Center(
        new Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage('oading.gif'),
            ),
          ),
        ),
      ),
    );
}

The http request:

void getData() async {

      final response = await http.get(Uri.parse(URL));
      if (response.statusCode == 200) {
          messageText = "Success"; 
      } else {
          messageText = "Something went wrong"; 
      }
}

This is the resulting page body that I’d like to show after the getData() function loads:

Widget build(BuildContext context) {
  return new Scaffold(
      appBar: AppBar(),
      body: SingleChildScrollView(
        child: Container(
          child: Text(messageText),
        ),
      ),
  );
}

2

Answers


    • Use a stateful widget
    • create a boolean for loading set to false
    • in your get data method, set the state of the variable to true
    • on getting a 200, set the state to false

    Something close to the below:

    class MyWidget extends StatefulWidget {
      const MyWidget({Key? key}) : super(key: key);
    
      @override
      State<MyWidget> createState() => _MyWidgetState();
    }
    
    class _MyWidgetState extends State<MyWidget> {
      bool isLoading = false;
      void getData() async {
        isLoading = true;
        if (mounted) setState(() {});
        final response = await http.get(Uri.parse(URL));
        if (response.statusCode == 200) {
          messageText = "Success";
          isLoading = false;
        } else {
          messageText = "Something went wrong";
          isLoading = false;
        }
        if (mounted) setState(() {});
      }
    
      @override
      void initState() {
        getData();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: isLoading ? null : AppBar(),
          body: isLoading
              ? Center(
                  child: Container(
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage('oading.gif'),
                      ),
                    ),
                  ),
                )
              : SingleChildScrollView(
                  child: Container(
                    child: Text(messageText),
                  ),
                ),
        );
      }
    }
    

    You can also use a future builder instead.

    Login or Signup to reply.
  1. You can use FutureBuilder to wait for your HTTP request async function to complete, and render the UI based on the results.

     Future<String> getData() async {
        String messageText;
        final response = await http.get(Uri.parse(URL));
        if (response.statusCode == 200) {
          messageText = "Success";
        } else {
          messageText = "Something went wrong";
        }
        return messageText; // change it to return the string value, from the function rather than assign it to the local variable,
      }
    
    
    Scaffold(
        body: FutureBuilder(
              future: getData(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return SingleChildScrollView(
                    child: Container(
                      child: Text(snapshot.data.toString()),
                    ),
                  );
                } else {
                  return Center(
                    child: Container(
                      decoration: const BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage('oading.gif'),
                        ),
                      ),
                    ),
                  );
                }
              },
            ),
      )
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search