1

I have this question how to show LinearProgressIndicator in my AppBar, when the user makes an API request like login, catch data from the server etc?

The following code is the menu:

import 'package:flutter/material.dart';
import 'package:simao/routes/app_routes.dart';
import 'package:simao/themes/themes.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class MenuScreen extends StatefulWidget {
  // Title of appbar
  final String title;
  // Screen to show
  final Widget screen;

  const MenuScreen({Key? key, required this.title, required this.screen}) : super(key: key);

  @override
  State<MenuScreen> createState() => _MenuScreenState();
}

class _MenuScreenState extends State<MenuScreen> {
  @override
  Widget build(BuildContext context) {
    // We need the information of menu options
    final menuOptions = AppRoutes.menuOptions;

    return Scaffold(
      appBar: AppBar(title: Text(widget.title),
          // linear loading bar
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(1.0),
            child:
              Column(children: [

                //
                // This when is loading show the LinearProgressIndicator
                //

                if(true)...[
                  LinearProgressIndicator(
                    minHeight: 2,
                    backgroundColor: AppTheme.white,
                    // valueColor: AlwaysStoppedAnimation<Color>(AppTheme.white),
                  ),
                ],


              ],
            ) 
          ),
      ),
      body: Center(
        child: widget.screen,
      ),
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.
        child: ListView(
          // Important: Remove any padding from the ListView.
          padding: EdgeInsets.zero,
          children: [
            DrawerHeader(
              decoration: const BoxDecoration(
                color: AppTheme.primaryColor,
              ),
              child: Column(
                children: const [
                  CircleAvatar(
                    radius: 40,
                    backgroundImage: AssetImage("lib/assets/logo_app/logo.png"),
                  ),
                  SizedBox(height: 10),
                  Text(
                    "Simao",
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 24,
                    ),
                  ),
                ],
              ),
            ),

            // Recorremos el menuOptions para crear los items
            ...menuOptions.map((item) => ListTile(
                  leading: FaIcon(item.icon),
                  title: Text(item.name),
                  onTap: () {
                    Navigator.pushNamed(context, item.route);
                  },
                )),

            const Divider(),

            SizedBox(
              width: double.infinity,
              child: ElevatedButton(
                style: ElevatedButton.styleFrom(
                  backgroundColor: AppTheme.dangerColor,
                  shadowColor: Colors.transparent,
                ),
                onPressed: () =>
                    Navigator.of(context).pushNamedAndRemoveUntil(AppRoutes.loginRoute, (route) => false),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: const [
                    Text('Cerrar Sesión'),
                    SizedBox(
                      width: 10,
                    ), // <-- Text
                    Icon(
                      Icons.exit_to_app,
                      size: 24.0,
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

The next code is to make an API request:

static Future<String> httpRequestAPI({required String rute, required Map<String, dynamic> body, int? timeOutSeconds = 10}) async {

    // SEND REQUEST TO SHOW LOADING ??

    if (!await HttpProvider().checkConnectivityState()) return json.encode(defaultResponses["noInternet"]);
    final url = Uri.https(HttpProvider.urlJFerrer, rute);
    final response = await http.post(url, headers: HttpProvider.headers, body: body)
        .timeout(Duration(seconds: timeOutSeconds!), onTimeout: () {
        return http.Response(json.encode(HttpProvider.defaultResponses['timeout']), 500);
    });

    // HIDE LOADING ??

    return response.body;
  }

LinearProgressIndicator

When the user makes an API request show the LinearProgressIndicator.

My Car
  • 4,198
  • 5
  • 17
  • 50

1 Answers1

0

create variable bool isLoading = false; which will contain when to show the indicator

in httpRequestAPI() before the request starts, set to true to start showing the indicator, when the response comes, then set to false I shortened the code for clarity

Future<String> httpRequestAPI() async {
    //Show indicator
    setState(() {
      isLoading = true;
    });
  
   //simulation of waiting for a request, just a random pause within 5000 milliseconds, when it ends, then the answer has come and the indicator needs to be hidden
   await Future.delayed(Duration(milliseconds: Random().nextInt(5000)), () {
     setState(() {
       isLoading = false;
     });
    });

    return "RESPONSE JSON STRING";
  }

 //if  isLoading == true show indicator else hide
 appBar: AppBar(
        title: isLoading ? const LinearProgressIndicator(color: Colors.deepOrange) : null,
 ),

complete code

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isLoading = false;


  Future<String> httpRequestAPI() async {

    setState(() {
      isLoading = true;
    });

   await Future.delayed(Duration(milliseconds: Random().nextInt(5000)), () {
     setState(() {
       isLoading = false;
     });
    });

    return "RESPONSE JSON STRING";
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: isLoading ? const LinearProgressIndicator(color: Colors.deepOrange,) : null,
      ),
      body: ElevatedButton(onPressed: () async {
       await httpRequestAPI();
      },child: const Text('API CALL'),)

    );
  }
}