Search code examples
flutterapidartflutter-layoutflutter-futurebuilder

How to show progress bar on button click in flutter


I am calling an API on button click but when I click on the button nothing happens. also I want to show a linear progress bar when the user clicks on the button uless/until data gets loaded but it is not working the way I expect it to work. Here is my code. I am a newbie. I am stuck on this problem please someone corrects my code so that it will work the way I expect.


class _MyHomePageState extends State<MyHomePage> {
  getFokatKiAdvice() async {
    final response =
        await http.get(Uri.parse("https://api.adviceslip.com/advice"));
    var resp = json.decode(response.body);
    print(resp);
    return resp['slip']['advice'];
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(10.0),
          child: Column(
            children: [
              const Card(
                child: ListTile(
                  title: Text(
                    "Advice for you !",
                    textAlign: TextAlign.center,
                  ),
                ),
              ),
              Card(
                child: Column(
                  children: [
                    ListTile(
                      title: FutureBuilder(
                        future: getFokatKiAdvice(),
                        builder:
                            (BuildContext context, AsyncSnapshot snapshot) {
                          if (snapshot.hasData) {
                            return Text(
                              snapshot.data,
                              textAlign: TextAlign.center,
                            );
                          } else if (snapshot.hasError) {
                            return const Text(
                                "Oye !! Thare pass Internet naahi hn !!");
                          } else {
                            return const LinearProgressIndicator();
                          }
                        },
                      ),
                    ),
                    const SizedBox(
                      height: 5.00,
                    ),
                    ElevatedButton(
                      onPressed: () {
                        getFokatKiAdvice();
                        // setState(() {});
                      },
                      child: const Text("Ghe Advice !"),
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Solution

  • You just need to make bool if its loading and getting data, the indicator shows up.

    class MyHomePage extends StatefulWidget {
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      String data;
      bool _isLoading;
      getFokatKiAdvice() async {
        final response =
            await http.get(Uri.parse("https://api.adviceslip.com/advice"));
        var resp = json.decode(response.body);
        if (response.statusCode != 200) {
          data = "Oye !! Thare pass Internet naahi hn !!";
        }
        print(resp);
        setState(() {
          data = resp['slip']['advice'];
          _isLoading = false;
        });
      }
    
      @override
      void initState() {
        _isLoading = true;
        getFokatKiAdvice();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Material App',
          home: Scaffold(
            body: Center(
              child: Padding(
                padding: const EdgeInsets.all(10.0),
                child: Column(
                  children: [
                    const Card(
                      child: ListTile(
                        title: Text(
                          "Advice for you !",
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                    Card(
                      child: Column(
                        children: [
                          ListTile(
                              title: _isLoading
                                  ? const LinearProgressIndicator()
                                  : Text(
                                      data,
                                      textAlign: TextAlign.center,
                                    )),
                          const SizedBox(
                            height: 5.00,
                          ),
                          ElevatedButton(
                            onPressed: () {
                              setState(() {
                                _isLoading = true;
                                data = '';
                              });
                              getFokatKiAdvice();
                            },
                            child: const Text("Ghe Advice !"),
                          ),
                          const SizedBox(
                            height: 10,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    

    here is my solution without futureB

    here is result

    here is result