Display full screen loading widget in flutter

Viewed 15628

I want to show full-screen loading view in flutter while API calling. But when I add loading widget in scaffold body it appears after appbar and bottom navigator.

I am spending lots of time for display loading view in full-screen. Also, I want to prevent back action while API calling.

4 Answers

Well, since you're using Scaffold, then make use of its showDialog() method.

It has a property called barrierDismissible that if you set as false, the user won't be able to close or interact with the screen outside of it.

void _openLoadingDialog(BuildContext context) {
  showDialog(
    barrierDismissible: false,
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        content: CircularProgressIndicator(),
      );
    },
  );
}

Once you're done with the API loading, call Navigator.pop(context); to dismiss the dialog.

To prevent the user from clicking the back button on the Dialog, dismissing it, envelop your Scaffold inside a WillPopScope widget and implement the onWillPop function.

@override
Widget build(BuildContext context) {
  return WillPopScope(
      child: Scaffold(
        body: Container(),
      ),
      onWillPop: _onBackButton
  );
}

Future<bool> _onBackButton() {
  // Implement your logic
  return Future.value(false);
}

If you return false on it, the user won't be able to press the back button. So use any logic you desire, e.g 'If I'm loading return false, otherwise return true'.

  1. Full-screen loader: Best solution to display a full screen loader is to use package https://pub.dev/packages/screen_loader.
  2. Prevent back action while loading: This package this package provides a variable isLoading, use it to prevent navigating back. eg:
// --------------- some_screen.dart ---------------
import 'package:flutter/material.dart';
import 'package:screen_loader/screen_loader.dart';

class SomeScreen extends StatefulWidget {
  @override
  _SomeScreenState createState() => _SomeScreenState();
}

class _SomeScreenState extends State<SomeScreen> with ScreenLoader<SomeScreen> {
  getData() {
    this.performFuture(NetworkService.callApi);
  }

  @override
  Widget screen(BuildContext context) {
    return WillPopScope(
      child: Scaffold(
          // your beautiful design..
          ),
      onWillPop: () async {
        return !isLoading;
      },
    );
  }
}

// --------------- app_api.dart ---------------
class NetworkService {
  static Future callApi() async {

  }
}

NOTE: You'll need to see the definition of performFuture to see how it works for different scenarios.

Did you not think of removing the Scaffold for the loading screen?

Related