modal_progress_hud 0.0.6

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new80

modal_progress_hud

A simple widget wrapper to enable modal progress HUD (a modal progress indicator)

pub package Build Status Coverage Status

Inspired by this article.

Demo

Demo

See example for details

Usage

ModalProgressHUD(child: _buildWidget(), inAsyncCall: _saving)

Simply wrap the widget as a child of ModalProgressHUD, typically a form, together with a boolean maintained in local state. On first loading, the boolean is false, and the child is displayed. After submitting, and before making the async call, set the local boolean to true. The child will redraw and will show the modal progress HUD. After they async call completes, set the boolean to false. The child will redraw without the modal progress indicator.

class SettingsPage extends StatefulWidget {
  @override
  _SettingsPageState createState() => new _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
  bool _saving = false;

  void _submit() {

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

    //Simulate a service call
    print('submitting to backend...');
    new Future.delayed(new Duration(seconds: 4), () {
      setState(() {
        _saving = false;
      });
    });
  }

  Widget _buildWidget() {
    return new Form(
      child: new Column(
        children: [
          new SwitchListTile(
            title: const Text('Bedroom'),
            value: _bedroom,
            onChanged: (bool value) {
              setState(() {
                _bedroom = value;
              });
            },
            secondary: const Icon(Icons.hotel),
          ),
          new RaisedButton(
            onPressed: _submit,
            child: new Text('Save'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Flutter Progress Indicator Demo'),
        backgroundColor: Colors.blue,
      ),
      body: ModalProgressHUD(child: _buildWidget(), inAsyncCall: _saving),
    );
  }
}

Example

See the example application source for a complete sample app using the modal progress HUD. Included in the example is a method for using a form's validators while making async calls (see flutter/issues/9688 for details).

Issues and feedback

Please file issues to send feedback or report a bug. Thank you!

[0.0.6]

  • Pass any progress indicator
  • Added tests and code coverage
  • Refactoring for tests

[0.0.5]

  • Changed layout of README and corrected spelling

[0.0.4]

  • Updated README

[0.0.3]

  • Fixed location of demo gif file

[0.0.2]

  • Added example of use of modal progress hud with login screen, form and async calls.

[0.0.1] - July 10, 2018

  • Simple countainer widget to enable modal progress hud (progress indicator)

example/lib/main.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(
        loginData: LoginData(),
      ),
    );
  }
}

class LoginPage extends StatefulWidget {
  final LoginData loginData;
  LoginPage({@required this.loginData});
  @override
  _LoginPageState createState() => _LoginPageState(loginData: loginData);
}

class _LoginPageState extends State<LoginPage> {
  final LoginData loginData;
  _LoginPageState({this.loginData});

  final GlobalKey<FormState> _loginFormKey = GlobalKey<FormState>();
  // manage state of modal progress HUD widget
  bool _inAsyncCall = false;

  final LoginData _validLoginData = LoginData(
    userName: 'username1',
    password: 'password1',
  );
  bool _isValidUserName = true; // managed by response from server
  bool _isValidPassword = true; // managed by response from server

  // validate user name
  String _validateUserName(String userName) {
    if (userName.length < 8) {
      return 'Username must be at least 8 characters';
    }

    if (!_isValidUserName) {
      _isValidUserName = true;
      return 'Incorrect user name';
    }

    return null;
  }

  // validate password
  String _validatePassword(String password) {
    if (password.length < 8) {
      return 'Password must be at least 8 characters';
    }

    if (!_isValidPassword) {
      _isValidPassword = true;
      return 'Incorrect password';
    }

    return null;
  }

  void _submit() {
    if (_loginFormKey.currentState.validate()) {
      _loginFormKey.currentState.save();

      // dismiss keyboard
      FocusScope.of(context).requestFocus(new FocusNode());

      // start the modal progress HUD
      setState(() {
        _inAsyncCall = true;
      });

      // Simulate a service call
      Future.delayed(Duration(seconds: 1), () {
        setState(() {
          if (loginData.userName == _validLoginData.userName)
            _isValidUserName = true;
          else
            _isValidUserName = false;
          if (loginData.password == _validLoginData.password)
            _isValidPassword = true;
          else
            _isValidPassword = false;
          if (_isValidUserName && _isValidPassword) {
            loginData.loggedIn = true;
          }
          // stop the modal progress HUD
          _inAsyncCall = false;
        });
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Modal Progress HUD Demo'),
        backgroundColor: Colors.blue,
      ),
      body: ModalProgressHUD(
        child: LoginForm(
          loginFormKey: _loginFormKey,
          submit: _submit,
          loginData: loginData,
          validateUserName: _validateUserName,
          validatePassword: _validatePassword,
        ),
        inAsyncCall: _inAsyncCall,
        // demo of some additional parameters
        opacity: 0.5,
        progressIndicator: CircularProgressIndicator(),
      ),
    );
  }
}

class LoginForm extends StatelessWidget {
  final GlobalKey<FormState> loginFormKey;
  final LoginData loginData;
  final Function validateUserName;
  final Function validatePassword;
  final Function submit;
  LoginForm({
    @required this.loginFormKey,
    @required this.submit,
    @required this.loginData,
    @required this.validateUserName,
    @required this.validatePassword,
  });

  @override
  Widget build(BuildContext context) {
    final ThemeData themeData = Theme.of(context);
    final TextTheme textTheme = themeData.textTheme;
    // run the validators on reload
    loginFormKey.currentState?.validate();
    return Form(
      key: this.loginFormKey,
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.fromLTRB(32.0, 4.0, 32.0, 4.0),
            child: TextFormField(
              key: Key('username'),
              initialValue: loginData.userName,
              keyboardType: TextInputType.text,
              decoration: InputDecoration(
                  hintText: 'enter username', labelText: 'User Name'),
              style: TextStyle(fontSize: 20.0, color: textTheme.button.color),
              validator: validateUserName,
              onSaved: (String value) {
                loginData.userName = value;
              },
            ),
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(32.0, 4.0, 32.0, 32.0),
            child: TextFormField(
              key: Key('password'),
              obscureText: true,
              initialValue: loginData.userName,
              keyboardType: TextInputType.text,
              decoration: InputDecoration(
                  hintText: 'enter password', labelText: 'Password'),
              style: TextStyle(fontSize: 20.0, color: textTheme.button.color),
              validator: validatePassword,
              onSaved: (String value) {
                loginData.password = value;
              },
            ),
          ),
          RaisedButton(
            key: Key('login'),
            onPressed: submit,
            child: Text('Login'),
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(32.0, 32.0, 32.0, 4.0),
            child: loginData.loggedIn
                ? Text(
                    'Login successful!',
                    key: Key('loggedIn'),
                    style: TextStyle(fontSize: 20.0),
                  )
                : Text(
                    'Not logged in',
                    key: Key('notLoggedIn'),
                    style: TextStyle(fontSize: 20.0),
                  ),
          ),
        ],
      ),
    );
  }
}

class LoginData {
  String userName;
  String password;
  bool loggedIn;
  LoginData({this.userName, this.password, this.loggedIn = false});

//  @override
//  String toString() {
//    return 'LoginData{\n'
//        '\tuserName = $userName\n'
//        '\tpassword = $password\n'
//        '\tloggedIn = $loggedIn\n'
//        '}';
//  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  modal_progress_hud: ^0.0.6

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:modal_progress_hud/modal_progress_hud.dart';
  
Version Uploaded Documentation Archive
0.0.6 Jul 14, 2018 Go to the documentation of modal_progress_hud 0.0.6 Download modal_progress_hud 0.0.6 archive
0.0.5 Jul 12, 2018 Go to the documentation of modal_progress_hud 0.0.5 Download modal_progress_hud 0.0.5 archive
0.0.4 Jul 11, 2018 Go to the documentation of modal_progress_hud 0.0.4 Download modal_progress_hud 0.0.4 archive
0.0.3 Jul 11, 2018 Go to the documentation of modal_progress_hud 0.0.3 Download modal_progress_hud 0.0.3 archive
0.0.2 Jul 11, 2018 Go to the documentation of modal_progress_hud 0.0.2 Download modal_progress_hud 0.0.2 archive
0.0.1 Jul 11, 2018 Go to the documentation of modal_progress_hud 0.0.1 Download modal_progress_hud 0.0.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
68
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
80
Learn more about scoring.

We analyzed this package on Jul 20, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.69.0
  • pana: 0.11.7
  • Flutter: 0.5.5

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Issues and suggestions

Support Dart 2 in pubspec.yaml.

The SDK constraint in pubspec.yaml doesn't allow the Dart 2.0.0 release. For information about upgrading it to be Dart 2 compatible, please see https://www.dartlang.org/dart-2#migration.

The description is too short.

Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

Package is pre-v1 release.

While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.19.0 <2.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.6 1.14.11
meta 1.1.5 1.1.6
sky_engine 0.0.99
typed_data 1.1.5 1.1.6
vector_math 2.0.6 2.0.7
Dev dependencies
flutter_test