GithubHelp home page GithubHelp logo

mmcc007 / modal_progress_hud Goto Github PK

View Code? Open in Web Editor NEW
157.0 7.0 71.0 1.47 MB

A simple modal progress HUD (heads-up display, or progress indicator) for flutter

License: MIT License

Java 1.65% Objective-C 3.41% Dart 79.51% Shell 15.43%
flutter dart flutter-demo flutter-driver flutter-test flutter-plugin form-validation progress-indicator modal-forms modal-dialog

modal_progress_hud's Introduction

modal_progress_hud

A simple widget wrapper to enable modal progress HUD (a modal progress indicator, HUD = Heads Up Display)

pub package Build Status Coverage Status

Inspired by this article.

Demo

Demo

See example for details

Usage

Add the package to your pubspec.yml file.

dependencies:
  modal_progress_hud: ^0.1.3

Next, import the library into your widget.

import 'package:modal_progress_hud/modal_progress_hud.dart';

Now, all you have to do is simply wrap your widget as a child of ModalProgressHUD, typically a form, together with a boolean that is maintained in local state.

...
bool _saving = false
...

@override
Widget build(BuildContext context) {
  return Scaffold(
     body: ModalProgressHUD(child: Container(
       Form(...)
     ), inAsyncCall: _saving),
  );
}

Options

The current parameters are customizable in the constructor

ModalProgressHUD(
  @required inAsyncCall: bool,
  @required child: Widget,
  opacity: double,
  color: Color,
  progressIndicator: CircularProgressIndicator,
  offset: double
  dismissible: bool,
);

Example

Here is an example app that demonstrates the usage.

  1. On initial load, _saving is false which causes your child widget to display
  2. When the form is submitted, _saving is set to true, which will display the modal
  3. Once the async call is complete, _saving is set back to false, hiding the modal
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),
    );
  }
}

Update: See this article on Medium about async form validation

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!

modal_progress_hud's People

Contributors

arsenioo avatar mmcc007 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

modal_progress_hud's Issues

dismissible attribute does not behave correctly

hi:
I'm using your library,but i found the dismissible attribute does not behave correctly.
I see that you use ModalBarrier widget,when set the dismissible as true,it will call Navigator.pop,but i think it should disappear the mask instead of pop

'package:flutter/src/rendering/object.dart': Failed assertion: line 1645 pos 12: '!_debugDoingThisLayout': is not true.

Hi

Thanks for a great plugin, but I just installed an I get this exception when using it

'package:flutter/src/rendering/object.dart': Failed assertion: line 1645 pos 12: '!_debugDoingThisLayout': is not true.

I followed the example on my project.

Here doctor output

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel master, v1.10.3-pre.46, on Microsoft Windows [Version 10.0.18362.418], locale en-ZA)
 
[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[!] Android Studio (version 3.4)
    X Flutter plugin not installed; this adds Flutter specific functionality.
    X Dart plugin not installed; this adds Dart specific functionality.
[√] VS Code (version 1.39.1)
[√] Connected device (1 available)

! Doctor found issues in 1 category.

xception thrown by package modal_progress_hud - its simple impl only

Steps to Reproduce
Basic Implementation of Flutter package :
https://pub.dartlang.org/packages/modal_progress_hud

as shown in the example.

Logs
I/flutter (28537): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (28537): The following assertion was thrown building LoginPage(dirty, state: _LoginPageState#f76d1):
I/flutter (28537): 'package:modal_progress_hud/modal_progress_hud.dart': Failed assertion: line 43 pos 16: 'child !=
I/flutter (28537): null': is not true.
I/flutter (28537):
I/flutter (28537): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (28537): more information in this error message to help you determine and fix the underlying cause.
I/flutter (28537): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (28537): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (28537):
I/flutter (28537): When the exception was thrown, this was the stack:
I/flutter (28537): #2 new ModalProgressHUD (package:modal_progress_hud/modal_progress_hud.dart:43:16)
I/flutter (28537): #3 _LoginPageState.build (package:flutter_app/page/login.dart:185:13)
I/flutter (28537): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter (28537): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter (28537): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28537): #7 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3701:5)

Navbar and keyboard

Hi!

Using the following settings, the navbar isn't being hidden when the keyboard appears

return Scaffold(
      body: PersistentTabView(
        controller: _controller,
        screens: _InitialWidgetState._pages
            .map((e) => SafeArea(child: e.value1))
            .toList(),
        items: _InitialWidgetState._pages
            .map((e) => PersistentBottomNavBarItem(
                  icon: e.value2,
                  title: e.value3,
                  inactiveColor: Colors.black,
                  titleFontSize: Theme.of(context).textTheme.bodyText2.fontSize,
                ))
            .toList(),
        popAllScreensOnTapOfSelectedTab: false,
        navBarHeight: 65,
        navBarStyle: NavBarStyle.style13,
        decoration: NavBarDecoration(
          borderRadius: BorderRadius.circular(15),
          boxShadow: const [BoxShadow()],
        ),
      ),
      
    );

Using in InitState()

How do we use this library when using an Async method in initState?
We have a dependency on Widget while in InitState, no widget has been created yet.

Global level

Hi @mmcc007 ,

Is it possible to make this at global level, say at MaterialApp level, so to avoid defining it in each widget form?

Thanks in advance.

Exception while using inside a ListView

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performLayout():
BoxConstraints forces an infinite height.

These invalid constraints were provided to RenderDecoratedBox's layout() function by the following function, which probably computed the invalid constraints in question:
  RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:270:13)
The offending constraints were: BoxConstraints(w=320.0, h=Infinity)
The relevant error-causing widget was
    ModalProgressHUD 
lib/…/welcome/user_profile_update_form.dart:58
When the exception was thrown, this was the stack
#0      BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError 
package:flutter/…/rendering/box.dart:519
#1      BoxConstraints.debugAssertIsValid.<anonymous closure> 
package:flutter/…/rendering/box.dart:563
#2      BoxConstraints.debugAssertIsValid 
package:flutter/…/rendering/box.dart:567
#3      RenderObject.layout 
package:flutter/…/rendering/object.dart:1672
#4      RenderConstrainedBox.performLayout 
package:flutter/…/rendering/proxy_box.dart:270
...

Minimum duration

Hi there,

How can we add a minimum duration?
For example the spinner will always take 2 seconds at least?

Spinner with text

Hello! Love your widget! Finally I found some loading plugin for my app that actually works.

Are you planning to let us insert some text above/under/side by side the spinner circle? Just to inform users which loading process is that. If it's a "Retrieving last updates" or "Loading your profile", to be clear for them.

If you don't plan, maybe I can try, if you let me, upgrading your code with this functionality. :) I would just add a String property with the text and something like a "TextPosition" property with constants like above, under, left and right.

Thanks!!!

Expose stack alignment

Im using your plugin with a bottomsheet and it aligned the bottomsheet to the top of the screen on load.

Editing the source fixed this:

return new Stack(
      alignment: Alignment.bottomCenter // Added this,
      children: widgetList,
    );

Pre-build stack in constructor for performance enhancement

You are welcome, thank you for implementing such good idea of modal hud!

Btw, I think that solution can be optimized even further because we can create a list of widgets for a stack right in the constructor, remove the most of logic and construction from the build function and only return there "child" or "stack" depending on async flag.

But the most important was done already: do not complicate the widgets hierarchy in the most common case when hud is off.

Originally posted by @arsenioo in #14 (comment)

bug

class login extends StatefulWidget {
const login({Key? key}) : super(key: key);

@OverRide
State createState() => _loginState();
}
const kTextFieldDecoration = InputDecoration(
hintText: 'Enter a value',
hintStyle: TextStyle(color: Colors.grey),
contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent, width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent, width: 2.0),
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
);
class _loginState extends State {
//final _passwordController = TextEditingController();
//String? _passwordError;
final formKey = GlobalKey();
//final _navKey = GlobalKey();
final _auth = FirebaseAuth.instance;
bool showSpinner = false;

// final _emailController = TextEditingController();
// String? _emailError;
void initstate(){
initstate();
requestPermission();
//getToken();
initInfo();
}
FlutterLocalNotificationsPlugin
flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
initInfo() async {
var androidInitialize = const AndroidInitializationSettings(
"@mipmap/ic_launcher");
var iosInitialize = const IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
//onDidReceiveLocalNotification: false
);
final InitializationSettings initializationSettings = InitializationSettings(
android: androidInitialize,
iOS: iosInitialize,
);

flutterLocalNotificationsPlugin.initialize(
    initializationSettings,
    onSelectNotification: (String? payload) async {
      try {
        if (payload != null && payload.isNotEmpty) {

        } else {}
      } catch (e) {

      }
      return;
    });
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
  print("............onMessage............");
  print("onMessage:${message.notification?.title}/${message.notification
      ?.body}}");
  BigTextStyleInformation bigTextStyleInformation = BigTextStyleInformation(
    message.notification!.body.toString(),
    htmlFormatBigText: true,
    contentTitle: message.notification!.title.toString(),
    htmlFormatContentTitle: true,
  );
  AndroidNotificationDetails androidPlatformChannelSpecifcs
  = AndroidNotificationDetails('User1', "User", importance: Importance.max,
      styleInformation: bigTextStyleInformation,
      priority: Priority.max,
      playSound: false);
});

var message;
var androidPlatformChannelSpecifics;
NotificationDetails platformChannelSpecifics = NotificationDetails(
    android: androidPlatformChannelSpecifics,
    iOS: const IOSNotificationDetails()
);

await flutterLocalNotificationsPlugin.show(
    0,
    "title",
    message.notification?.body,
    platformChannelSpecifics as NotificationDetails?,
    payload: message.data['title']);

}

FuturerequestPermission() async {
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
//authorizationStatus: authorizationStatus,
badge: true,
carPlay: false,
criticalAlert: false,
sound: true);
if(settings.authorizationStatus == AuthorizationStatus.authorized){
print("user granted permission");

}else if(settings.authorizationStatus == AuthorizationStatus.provisional) {
  print("User granted provisonal permission");
}else{
  print('user declined or hasnot accepted permission');
}

}

String? mtoken = "";
static const users = const {
'[email protected]': '123545',
'[email protected]': 'hunter'
};

Duration get loginTime => Duration(milliseconds: 2250);

Future<String?> authUser(LoginData data) {
debugPrint('Name: ${data.name},'
'Password: ${data.password}');
return Future.delayed(loginTime).then((
) {
if (!users.containsKey(data.name)) {
return 'User not exists';
}
if (users[data.name] != data.password) {
return 'Password doesnot match';
}
return null;
});
}

Future<String?> signupUser(SignupData data) {
debugPrint('sign up: ${data.name},Password: ${data.password}');
return Future.delayed(loginTime).then((
) =>
null
);
}

void saveToken(String token) async {
await FirebaseFirestore.instance.collection("UserTokens")
.doc("User1").set({
"token": token
});
}

Future<String?> recoverPassword(String name) {
debugPrint('Name: $name');
return Future.delayed(loginTime).then((
) {
if (!users.containsKey(name)) {
return 'User doesnot exist';
}
return null;
});
}

void getToken() async {
await FirebaseMessaging.instance.getToken().then(
(token) {
setState(() {
mtoken = token;
if (kDebugMode) {
print("My token is $mtoken");
}
});
saveToken(token!);
}
);
}
static const String routeName = '/list_screen';

//final navKey = GlobalKey();
static int selectedCategory = 0;
static Route route(Map<String, dynamic> args) {
return MaterialPageRoute(
builder: (
) => login(),
settings: RouteSettings(name: routeName),
);
}
late String email;
late String password;
/** List lists = List.generate(categories.length,
(index) => CategoryItem(
data: categories[index],
selected: index == selectedCategory,));**/
@OverRide
Widget build(BuildContext context) {
final propertyProvider = context.watch();
//var user = Provider.of(context);
final asyncValueOfProps = propertyProvider.asyncValueOfProps;
return Scaffold(
backgroundColor: Colors.white,
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 24.0
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
keyboardType: TextInputType.emailAddress,
textAlign: TextAlign.center,
onChanged: (value) {
email = value;
//Do something with the user input.
},
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your email')),
SizedBox(height: 4,),
TextField( obscureText: true,
textAlign: TextAlign.center,
onChanged: (value) {
password = value;
//Do something with the user input.
},
decoration: kTextFieldDecoration.copyWith(
hintText: 'Enter your Password')),
SizedBox(
height: 24.0,
),
ElevatedButton(
// statesController: ,
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
final newUser = await _auth
.createUserWithEmailAndPassword(
email: email, password: password);
if (newUser != null) {
Navigator.pushNamed(context, 'home_screen');
}
} catch (e) {
print(e);
}
setState(() {
showSpinner = false;
},
);
}, child: const Text("Sign up",
style: CupertinoTextField.cupertinoMisspelledTextStyle,),),
], ),
),

     ),

);
}
}
that is my class
for a login page

below is the error message
Screenshot 2023-02-12 174231

close the progress indicator

hello, I tried to add a function to close the progress indicator manualy (button) or automaticaly (delay) but I havn't succeded. I would add the posibility for the user to close the progress indicator if there is no connection.

HUD is not appearing

Hi,

I got this error from logs:

I/flutter (29162): Another exception was thrown: BoxConstraints forces an infinite height.
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderConstrainedBox#5e18e relayoutBoundary=up15 NEEDS-PAINT
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderSemanticsAnnotations#32bdb relayoutBoundary=up14 NEEDS-PAINT
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderPointerListener#980e2 relayoutBoundary=up13 NEEDS-PAINT
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderSemanticsGestureHandler#24ed8 relayoutBoundary=up12 NEEDS-PAINT
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderExcludeSemantics#76cbb relayoutBoundary=up11 NEEDS-PAINT
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderBlockSemantics#56409 relayoutBoundary=up10 NEEDS-PAINT
I/flutter (29162): Another exception was thrown: RenderBox was not laid out: RenderOpacity#6bd88 relayoutBoundary=up9 NEEDS-PAINT

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.