How work with progress indicator in flutter












19















I'm newbie in flutter and wanted to know what is better way to add CircularProgressIndicator in my layout. For example, my login view. This view have username, password and login Button. I did want create a overlay layout (with Opacity) that, when loading, show progress indicator like I use in NativeScript, but I'm little confused with how to do and too if it is the better way. On NativeScript, for example, I add IndicatorActivity in main layout and set busy to true or false, so it overlay all view components when is loading.



Edit:



I was able to reach this result:



    void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

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

void _onLoading() {
setState(() {
_loading = true;
new Future.delayed(new Duration(seconds: 3), _login);
});
}


Future _login() async{
setState((){
_loading = false;
});
}

@override
Widget build(BuildContext context) {


var body = new Column(
children: <Widget>[
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.fromLTRB(15.0, 150.0, 15.0, 0.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "username"),
),
),
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.all(15.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "password"),
),
),
],
);


var bodyProgress = new Container(
child: new Stack(
children: <Widget>[
body,
new Container(
alignment: AlignmentDirectional.center,
decoration: new BoxDecoration(
color: Colors.white70,
),
child: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200],
borderRadius: new BorderRadius.circular(10.0)
),
width: 300.0,
height: 200.0,
alignment: AlignmentDirectional.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new SizedBox(
height: 50.0,
width: 50.0,
child: new CircularProgressIndicator(
value: null,
strokeWidth: 7.0,
),
),
),
new Container(
margin: const EdgeInsets.only(top: 25.0),
child: new Center(
child: new Text(
"loading.. wait...",
style: new TextStyle(
color: Colors.white
),
),
),
),
],
),
),
),
],
),
);

return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200]
),
child: _loading ? bodyProgress : body
),
floatingActionButton: new FloatingActionButton(
onPressed: _onLoading,
tooltip: 'Loading',
child: new Icon(Icons.check),
),
);
}
}


app screen result



I'm still adapting to the idea of ​​states. This code is within the expected when working with flutter?



Thanks!










share|improve this question

























  • Please post your code

    – SherylHohman
    Nov 2 '17 at 0:09
















19















I'm newbie in flutter and wanted to know what is better way to add CircularProgressIndicator in my layout. For example, my login view. This view have username, password and login Button. I did want create a overlay layout (with Opacity) that, when loading, show progress indicator like I use in NativeScript, but I'm little confused with how to do and too if it is the better way. On NativeScript, for example, I add IndicatorActivity in main layout and set busy to true or false, so it overlay all view components when is loading.



Edit:



I was able to reach this result:



    void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

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

void _onLoading() {
setState(() {
_loading = true;
new Future.delayed(new Duration(seconds: 3), _login);
});
}


Future _login() async{
setState((){
_loading = false;
});
}

@override
Widget build(BuildContext context) {


var body = new Column(
children: <Widget>[
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.fromLTRB(15.0, 150.0, 15.0, 0.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "username"),
),
),
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.all(15.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "password"),
),
),
],
);


var bodyProgress = new Container(
child: new Stack(
children: <Widget>[
body,
new Container(
alignment: AlignmentDirectional.center,
decoration: new BoxDecoration(
color: Colors.white70,
),
child: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200],
borderRadius: new BorderRadius.circular(10.0)
),
width: 300.0,
height: 200.0,
alignment: AlignmentDirectional.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new SizedBox(
height: 50.0,
width: 50.0,
child: new CircularProgressIndicator(
value: null,
strokeWidth: 7.0,
),
),
),
new Container(
margin: const EdgeInsets.only(top: 25.0),
child: new Center(
child: new Text(
"loading.. wait...",
style: new TextStyle(
color: Colors.white
),
),
),
),
],
),
),
),
],
),
);

return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200]
),
child: _loading ? bodyProgress : body
),
floatingActionButton: new FloatingActionButton(
onPressed: _onLoading,
tooltip: 'Loading',
child: new Icon(Icons.check),
),
);
}
}


app screen result



I'm still adapting to the idea of ​​states. This code is within the expected when working with flutter?



Thanks!










share|improve this question

























  • Please post your code

    – SherylHohman
    Nov 2 '17 at 0:09














19












19








19


10






I'm newbie in flutter and wanted to know what is better way to add CircularProgressIndicator in my layout. For example, my login view. This view have username, password and login Button. I did want create a overlay layout (with Opacity) that, when loading, show progress indicator like I use in NativeScript, but I'm little confused with how to do and too if it is the better way. On NativeScript, for example, I add IndicatorActivity in main layout and set busy to true or false, so it overlay all view components when is loading.



Edit:



I was able to reach this result:



    void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

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

void _onLoading() {
setState(() {
_loading = true;
new Future.delayed(new Duration(seconds: 3), _login);
});
}


Future _login() async{
setState((){
_loading = false;
});
}

@override
Widget build(BuildContext context) {


var body = new Column(
children: <Widget>[
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.fromLTRB(15.0, 150.0, 15.0, 0.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "username"),
),
),
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.all(15.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "password"),
),
),
],
);


var bodyProgress = new Container(
child: new Stack(
children: <Widget>[
body,
new Container(
alignment: AlignmentDirectional.center,
decoration: new BoxDecoration(
color: Colors.white70,
),
child: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200],
borderRadius: new BorderRadius.circular(10.0)
),
width: 300.0,
height: 200.0,
alignment: AlignmentDirectional.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new SizedBox(
height: 50.0,
width: 50.0,
child: new CircularProgressIndicator(
value: null,
strokeWidth: 7.0,
),
),
),
new Container(
margin: const EdgeInsets.only(top: 25.0),
child: new Center(
child: new Text(
"loading.. wait...",
style: new TextStyle(
color: Colors.white
),
),
),
),
],
),
),
),
],
),
);

return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200]
),
child: _loading ? bodyProgress : body
),
floatingActionButton: new FloatingActionButton(
onPressed: _onLoading,
tooltip: 'Loading',
child: new Icon(Icons.check),
),
);
}
}


app screen result



I'm still adapting to the idea of ​​states. This code is within the expected when working with flutter?



Thanks!










share|improve this question
















I'm newbie in flutter and wanted to know what is better way to add CircularProgressIndicator in my layout. For example, my login view. This view have username, password and login Button. I did want create a overlay layout (with Opacity) that, when loading, show progress indicator like I use in NativeScript, but I'm little confused with how to do and too if it is the better way. On NativeScript, for example, I add IndicatorActivity in main layout and set busy to true or false, so it overlay all view components when is loading.



Edit:



I was able to reach this result:



    void main() {
runApp(new MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

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

void _onLoading() {
setState(() {
_loading = true;
new Future.delayed(new Duration(seconds: 3), _login);
});
}


Future _login() async{
setState((){
_loading = false;
});
}

@override
Widget build(BuildContext context) {


var body = new Column(
children: <Widget>[
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.fromLTRB(15.0, 150.0, 15.0, 0.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "username"),
),
),
new Container(
height: 40.0,
padding: const EdgeInsets.all(10.0),
margin: const EdgeInsets.all(15.0),
decoration: new BoxDecoration(
color: Colors.white,
),
child: new TextField(
decoration: new InputDecoration.collapsed(hintText: "password"),
),
),
],
);


var bodyProgress = new Container(
child: new Stack(
children: <Widget>[
body,
new Container(
alignment: AlignmentDirectional.center,
decoration: new BoxDecoration(
color: Colors.white70,
),
child: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200],
borderRadius: new BorderRadius.circular(10.0)
),
width: 300.0,
height: 200.0,
alignment: AlignmentDirectional.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new SizedBox(
height: 50.0,
width: 50.0,
child: new CircularProgressIndicator(
value: null,
strokeWidth: 7.0,
),
),
),
new Container(
margin: const EdgeInsets.only(top: 25.0),
child: new Center(
child: new Text(
"loading.. wait...",
style: new TextStyle(
color: Colors.white
),
),
),
),
],
),
),
),
],
),
);

return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Container(
decoration: new BoxDecoration(
color: Colors.blue[200]
),
child: _loading ? bodyProgress : body
),
floatingActionButton: new FloatingActionButton(
onPressed: _onLoading,
tooltip: 'Loading',
child: new Icon(Icons.check),
),
);
}
}


app screen result



I'm still adapting to the idea of ​​states. This code is within the expected when working with flutter?



Thanks!







dart flutter






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 2 '17 at 9:43









aziza

8,18222847




8,18222847










asked Nov 1 '17 at 23:12









Ricardo BocchiRicardo Bocchi

126139




126139













  • Please post your code

    – SherylHohman
    Nov 2 '17 at 0:09



















  • Please post your code

    – SherylHohman
    Nov 2 '17 at 0:09

















Please post your code

– SherylHohman
Nov 2 '17 at 0:09





Please post your code

– SherylHohman
Nov 2 '17 at 0:09












8 Answers
8






active

oldest

votes


















23














In flutter, there are a few way to deal with Async actions.



An lazy way to do it can be using a modal. Which will block the user input, thus preventing any unwanted actions.
This would require very little change to your code. Just modifying your _onLoading to something like this :



void _onLoading() {
showDialog(
context: context,
barrierDismissible: false,
child: new Dialog(
child: new Row(
mainAxisSize: MainAxisSize.min,
children: [
new CircularProgressIndicator(),
new Text("Loading"),
],
),
),
);
new Future.delayed(new Duration(seconds: 3), () {
Navigator.pop(context); //pop dialog
_login();
});
}


The most ideal way to do it is using FutureBuilder and a stateful widget. Which is what you started.
The trick is that, instead of having a boolean loading = false in your state, you can directly use a Future<MyUser> user



And then pass it as argument to FutureBuilder, which will give you some info such as "hasData" or the instance of MyUser when completed.



This would lead to something like this :



@immutable
class MyUser {
final String name;

MyUser(this.name);
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
Future<MyUser> user;

void _logIn() {
setState(() {
user = new Future.delayed(const Duration(seconds: 3), () {
return new MyUser("Toto");
});
});
}

Widget _buildForm(AsyncSnapshot<MyUser> snapshot) {
var floatBtn = new RaisedButton(
onPressed:
snapshot.connectionState == ConnectionState.none ? _logIn : null,
child: new Icon(Icons.save),
);
var action =
snapshot.connectionState != ConnectionState.none && !snapshot.hasData
? new Stack(
alignment: FractionalOffset.center,
children: <Widget>[
floatBtn,
new CircularProgressIndicator(
backgroundColor: Colors.red,
),
],
)
: floatBtn;

return new ListView(
padding: const EdgeInsets.all(15.0),
children: <Widget>[
new ListTile(
title: new TextField(),
),
new ListTile(
title: new TextField(obscureText: true),
),
new Center(child: action)
],
);
}

@override
Widget build(BuildContext context) {
return new FutureBuilder(
future: user,
builder: (context, AsyncSnapshot<MyUser> snapshot) {
if (snapshot.hasData) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Hello ${snapshot.data.name}"),
),
);
} else {
return new Scaffold(
appBar: new AppBar(
title: new Text("Connection"),
),
body: _buildForm(snapshot),
);
}
},
);
}
}





share|improve this answer
























  • Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

    – Ricardo Bocchi
    Nov 2 '17 at 16:49











  • a question off topic.. to each TextField I need a TextEditingController unique?

    – Ricardo Bocchi
    Nov 2 '17 at 17:36











  • @RicardoBocchi Yes

    – aziza
    Nov 2 '17 at 19:59











  • I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

    – aziza
    Nov 2 '17 at 23:02











  • Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

    – Rémi Rousselet
    Nov 3 '17 at 1:20





















13














For me, one neat way to do this is to show a SnackBar at the bottom while the Signing-In process is taken place, this is a an example of what I mean:



enter image description here



Here is how to setup the SnackBar.



Define a global key for your Scaffold



final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();


Add it to your Scaffold key attribute



return new Scaffold(
key: _scaffoldKey,
.......


My SignIn button onPressed callback:



onPressed: () {
_scaffoldKey.currentState.showSnackBar(
new SnackBar(duration: new Duration(seconds: 4), content:
new Row(
children: <Widget>[
new CircularProgressIndicator(),
new Text(" Signing-In...")
],
),
));
_handleSignIn()
.whenComplete(() =>
Navigator.of(context).pushNamed("/Home")
);
}


It really depends on how you want to build your layout, and I am not sure what you have in mind.



Edit



You probably want it this way, I have used a Stack to achieve this result and just show or hide my indicator based on onPressed



enter image description here



class TestSignInView extends StatefulWidget {
@override
_TestSignInViewState createState() => new _TestSignInViewState();
}


class _TestSignInViewState extends State<TestSignInView> {
bool _load = false;
@override
Widget build(BuildContext context) {
Widget loadingIndicator =_load? new Container(
color: Colors.grey[300],
width: 70.0,
height: 70.0,
child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
):new Container();
return new Scaffold(
backgroundColor: Colors.white,
body: new Stack(children: <Widget>[new Padding(
padding: const EdgeInsets.symmetric(vertical: 50.0, horizontal: 20.0),
child: new ListView(

children: <Widget>[
new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center
,children: <Widget>[
new TextField(),
new TextField(),

new FlatButton(color:Colors.blue,child: new Text('Sign In'),
onPressed: () {
setState((){
_load=true;
});

//Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new HomeTest()));
}
),

],),],
),),
new Align(child: loadingIndicator,alignment: FractionalOffset.center,),

],));
}

}





share|improve this answer


























  • Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

    – Ricardo Bocchi
    Nov 2 '17 at 1:41











  • Hey, I do not understand your question?

    – aziza
    Nov 2 '17 at 1:46











  • In my code, when _loading change, all views are rebuild. Is that so?

    – Ricardo Bocchi
    Nov 2 '17 at 1:52






  • 1





    Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

    – Rémi Rousselet
    Nov 2 '17 at 9:12






  • 1





    Okey, let me bake something.

    – Rémi Rousselet
    Nov 2 '17 at 9:18



















6














1. Without plugin



    class IndiSampleState extends State<ProgHudPage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Demo'),
),
body: Center(
child: RaisedButton(
color: Colors.blueAccent,
child: Text('Login'),
onPressed: () async {
showDialog(
context: context,
builder: (BuildContext context) {
return Center(child: CircularProgressIndicator(),);
});
await loginAction();
Navigator.pop(context);
},
),
));
}

Future<bool> loginAction() async {
//replace the below line of code with your login request
await new Future.delayed(const Duration(seconds: 2));
return true;
}
}


2. With plugin



check this plugin progress_hud



add the dependency in the pubspec.yaml file



dev_dependencies:
progress_hud:


import the package



import 'package:progress_hud/progress_hud.dart';


Sample code is given below to show and hide the indicator



class ProgHudPage extends StatefulWidget {
@override
_ProgHudPageState createState() => _ProgHudPageState();
}

class _ProgHudPageState extends State<ProgHudPage> {
ProgressHUD _progressHUD;
@override
void initState() {
_progressHUD = new ProgressHUD(
backgroundColor: Colors.black12,
color: Colors.white,
containerColor: Colors.blue,
borderRadius: 5.0,
loading: false,
text: 'Loading...',
);
super.initState();
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('ProgressHUD Demo'),
),
body: new Stack(
children: <Widget>[
_progressHUD,
new Positioned(
child: RaisedButton(
color: Colors.blueAccent,
child: Text('Login'),
onPressed: () async{
_progressHUD.state.show();
await loginAction();
_progressHUD.state.dismiss();
},
),
bottom: 30.0,
right: 10.0)
],
));
}

Future<bool> loginAction()async{
//replace the below line of code with your login request
await new Future.delayed(const Duration(seconds: 2));
return true;
}
}





share|improve this answer





















  • 3





    Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

    – Vladtn
    Apr 4 '18 at 10:19






  • 1





    Its not working.

    – prashant fepale
    Jul 4 '18 at 7:57






  • 2





    the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

    – prashant0205
    Jul 23 '18 at 10:25











  • Should you really add this as a Dev Dependency?

    – George
    Dec 25 '18 at 14:39











  • This plugin is not working!!!

    – Idee
    Jan 3 at 15:35



















5














Create a bool isLoading and set it to false. With the help of ternary operator, When user clicks on login button set state of isLoading to true. You will get circular loading indicator in place of login button



 isLoading ? new PrimaryButton(
key: new Key('login'),
text: 'Login',
height: 44.0,
onPressed: SetState((){isLoading = ture;}))
: Center(
child: CircularProgressIndicator(),
),


You can see Screenshots how it looks while before login clicked
enter image description here



After login clicked
enter image description here



In mean time you can run login process and login user. If user credentials are wrong then again you will setState of isLoading to false, such that loading indicator will become invisible and login button visible to user.
By the way, primaryButton used in code is my custom button. You can do same with OnPressed in button.






share|improve this answer
























  • That's actually pretty smart! No need to handle double click etc. Thanks.

    – Benobab
    Feb 2 at 21:03



















3














I took the following approach, which uses a simple modal progress indicator widget that wraps whatever you want to make modal during an async call.



The example in the package also addresses how to handle form validation while making async calls to validate the form (see flutter/issues/9688 for details of this problem). For example, without leaving the form, this async form validation method can be used to validate a new user name against existing names in a database while signing up.



https://pub.dartlang.org/packages/modal_progress_hud



Here is the demo of the example provided with the package (with source code):



async form validation with modal progress indicator



Example could be adapted to other modal progress indicator behaviour (like different animations, additional text in modal, etc..).






share|improve this answer































    0














    This is my solution with stack



    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    import 'dart:async';

    final themeColor = new Color(0xfff5a623);
    final primaryColor = new Color(0xff203152);
    final greyColor = new Color(0xffaeaeae);
    final greyColor2 = new Color(0xffE8E8E8);

    class LoadindScreen extends StatefulWidget {
    LoadindScreen({Key key, this.title}) : super(key: key);
    final String title;
    @override
    LoginScreenState createState() => new LoginScreenState();
    }

    class LoginScreenState extends State<LoadindScreen> {
    SharedPreferences prefs;

    bool isLoading = false;

    Future<Null> handleSignIn() async {
    setState(() {
    isLoading = true;
    });
    prefs = await SharedPreferences.getInstance();
    var isLoadingFuture = Future.delayed(const Duration(seconds: 3), () {
    return false;
    });
    isLoadingFuture.then((response) {
    setState(() {
    isLoading = response;
    });
    });
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text(
    widget.title,
    style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
    ),
    centerTitle: true,
    ),
    body: Stack(
    children: <Widget>[
    Center(
    child: FlatButton(
    onPressed: handleSignIn,
    child: Text(
    'SIGN IN WITH GOOGLE',
    style: TextStyle(fontSize: 16.0),
    ),
    color: Color(0xffdd4b39),
    highlightColor: Color(0xffff7f7f),
    splashColor: Colors.transparent,
    textColor: Colors.white,
    padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
    ),

    // Loading
    Positioned(
    child: isLoading
    ? Container(
    child: Center(
    child: CircularProgressIndicator(
    valueColor: AlwaysStoppedAnimation<Color>(themeColor),
    ),
    ),
    color: Colors.white.withOpacity(0.8),
    )
    : Container(),
    ),
    ],
    ));
    }
    }





    share|improve this answer































      0














      You can use FutureBuilder widget instead. This takes an argument which must be a Future. Then you can use a snapshot which is the state at the time being of the async call when loging in, once it ends the state of the async function return will be updated and the future builder will rebuild itself so you can then ask for the new state.



      FutureBuilder(
      future: myFutureFunction(),
      builder: (context, AsyncSnapshot<List<item>> snapshot) {
      if (!snapshot.hasData) {
      return Center(
      child: CircularProgressIndicator(),
      );
      } else {
      //Send the user to the next page.
      },
      );


      Here you have an example on how to build a Future



      Future<void> myFutureFunction() async{
      await callToApi();}





      share|improve this answer































        0














        class Loader extends StatefulWidget {
        @override
        State createState() => LoaderState();
        }

        class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
        AnimationController controller;
        Animation<double> animation;

        @override
        void initState() {
        super.initState();
        controller = AnimationController(
        duration: Duration(milliseconds: 1200), vsync: this);
        animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
        animation.addListener(() {
        this.setState(() {});
        });
        animation.addStatusListener((AnimationStatus status) {});
        controller.repeat();
        }

        @override
        void dispose() {
        controller.dispose();
        super.dispose();
        }

        @override
        Widget build(BuildContext context) {
        return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
        Container(
        color: Colors.blue,
        height: 3.0,
        width: animation.value * 100.0,
        ),
        Padding(
        padding: EdgeInsets.only(bottom: 5.0),
        ),
        Container(
        color: Colors.blue[300],
        height: 3.0,
        width: animation.value * 75.0,
        ),
        Padding(
        padding: EdgeInsets.only(bottom: 5.0),
        ),
        Container(
        color: Colors.blue,
        height: 3.0,
        width: animation.value * 50.0,
        )
        ],
        );
        }
        }


        Expanded(
        child: Padding(
        padding:
        EdgeInsets.only(left: 20.0, right: 5.0, top:20.0),
        child: GestureDetector(
        onTap: () {
        Navigator.push(
        context,
        MaterialPageRoute(
        builder: (context) => FirstScreen()));
        },
        child: Container(
        alignment: Alignment.center,
        height: 45.0,
        decoration: BoxDecoration(
        color: Color(0xFF1976D2),
        borderRadius: BorderRadius.circular(9.0)),
        child: Text('Login',
        style: TextStyle(
        fontSize: 20.0, color: Colors.white))),
        ),
        ),
        ),





        share|improve this answer
























        • How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

          – Max Zubko
          Dec 24 '18 at 21:01











        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47065098%2fhow-work-with-progress-indicator-in-flutter%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        8 Answers
        8






        active

        oldest

        votes








        8 Answers
        8






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        23














        In flutter, there are a few way to deal with Async actions.



        An lazy way to do it can be using a modal. Which will block the user input, thus preventing any unwanted actions.
        This would require very little change to your code. Just modifying your _onLoading to something like this :



        void _onLoading() {
        showDialog(
        context: context,
        barrierDismissible: false,
        child: new Dialog(
        child: new Row(
        mainAxisSize: MainAxisSize.min,
        children: [
        new CircularProgressIndicator(),
        new Text("Loading"),
        ],
        ),
        ),
        );
        new Future.delayed(new Duration(seconds: 3), () {
        Navigator.pop(context); //pop dialog
        _login();
        });
        }


        The most ideal way to do it is using FutureBuilder and a stateful widget. Which is what you started.
        The trick is that, instead of having a boolean loading = false in your state, you can directly use a Future<MyUser> user



        And then pass it as argument to FutureBuilder, which will give you some info such as "hasData" or the instance of MyUser when completed.



        This would lead to something like this :



        @immutable
        class MyUser {
        final String name;

        MyUser(this.name);
        }

        class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
        return new MaterialApp(
        title: 'Flutter Demo',
        home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
        }
        }

        class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);

        final String title;

        @override
        _MyHomePageState createState() => new _MyHomePageState();
        }

        class _MyHomePageState extends State<MyHomePage> {
        Future<MyUser> user;

        void _logIn() {
        setState(() {
        user = new Future.delayed(const Duration(seconds: 3), () {
        return new MyUser("Toto");
        });
        });
        }

        Widget _buildForm(AsyncSnapshot<MyUser> snapshot) {
        var floatBtn = new RaisedButton(
        onPressed:
        snapshot.connectionState == ConnectionState.none ? _logIn : null,
        child: new Icon(Icons.save),
        );
        var action =
        snapshot.connectionState != ConnectionState.none && !snapshot.hasData
        ? new Stack(
        alignment: FractionalOffset.center,
        children: <Widget>[
        floatBtn,
        new CircularProgressIndicator(
        backgroundColor: Colors.red,
        ),
        ],
        )
        : floatBtn;

        return new ListView(
        padding: const EdgeInsets.all(15.0),
        children: <Widget>[
        new ListTile(
        title: new TextField(),
        ),
        new ListTile(
        title: new TextField(obscureText: true),
        ),
        new Center(child: action)
        ],
        );
        }

        @override
        Widget build(BuildContext context) {
        return new FutureBuilder(
        future: user,
        builder: (context, AsyncSnapshot<MyUser> snapshot) {
        if (snapshot.hasData) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Hello ${snapshot.data.name}"),
        ),
        );
        } else {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Connection"),
        ),
        body: _buildForm(snapshot),
        );
        }
        },
        );
        }
        }





        share|improve this answer
























        • Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

          – Ricardo Bocchi
          Nov 2 '17 at 16:49











        • a question off topic.. to each TextField I need a TextEditingController unique?

          – Ricardo Bocchi
          Nov 2 '17 at 17:36











        • @RicardoBocchi Yes

          – aziza
          Nov 2 '17 at 19:59











        • I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

          – aziza
          Nov 2 '17 at 23:02











        • Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

          – Rémi Rousselet
          Nov 3 '17 at 1:20


















        23














        In flutter, there are a few way to deal with Async actions.



        An lazy way to do it can be using a modal. Which will block the user input, thus preventing any unwanted actions.
        This would require very little change to your code. Just modifying your _onLoading to something like this :



        void _onLoading() {
        showDialog(
        context: context,
        barrierDismissible: false,
        child: new Dialog(
        child: new Row(
        mainAxisSize: MainAxisSize.min,
        children: [
        new CircularProgressIndicator(),
        new Text("Loading"),
        ],
        ),
        ),
        );
        new Future.delayed(new Duration(seconds: 3), () {
        Navigator.pop(context); //pop dialog
        _login();
        });
        }


        The most ideal way to do it is using FutureBuilder and a stateful widget. Which is what you started.
        The trick is that, instead of having a boolean loading = false in your state, you can directly use a Future<MyUser> user



        And then pass it as argument to FutureBuilder, which will give you some info such as "hasData" or the instance of MyUser when completed.



        This would lead to something like this :



        @immutable
        class MyUser {
        final String name;

        MyUser(this.name);
        }

        class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
        return new MaterialApp(
        title: 'Flutter Demo',
        home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
        }
        }

        class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);

        final String title;

        @override
        _MyHomePageState createState() => new _MyHomePageState();
        }

        class _MyHomePageState extends State<MyHomePage> {
        Future<MyUser> user;

        void _logIn() {
        setState(() {
        user = new Future.delayed(const Duration(seconds: 3), () {
        return new MyUser("Toto");
        });
        });
        }

        Widget _buildForm(AsyncSnapshot<MyUser> snapshot) {
        var floatBtn = new RaisedButton(
        onPressed:
        snapshot.connectionState == ConnectionState.none ? _logIn : null,
        child: new Icon(Icons.save),
        );
        var action =
        snapshot.connectionState != ConnectionState.none && !snapshot.hasData
        ? new Stack(
        alignment: FractionalOffset.center,
        children: <Widget>[
        floatBtn,
        new CircularProgressIndicator(
        backgroundColor: Colors.red,
        ),
        ],
        )
        : floatBtn;

        return new ListView(
        padding: const EdgeInsets.all(15.0),
        children: <Widget>[
        new ListTile(
        title: new TextField(),
        ),
        new ListTile(
        title: new TextField(obscureText: true),
        ),
        new Center(child: action)
        ],
        );
        }

        @override
        Widget build(BuildContext context) {
        return new FutureBuilder(
        future: user,
        builder: (context, AsyncSnapshot<MyUser> snapshot) {
        if (snapshot.hasData) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Hello ${snapshot.data.name}"),
        ),
        );
        } else {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Connection"),
        ),
        body: _buildForm(snapshot),
        );
        }
        },
        );
        }
        }





        share|improve this answer
























        • Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

          – Ricardo Bocchi
          Nov 2 '17 at 16:49











        • a question off topic.. to each TextField I need a TextEditingController unique?

          – Ricardo Bocchi
          Nov 2 '17 at 17:36











        • @RicardoBocchi Yes

          – aziza
          Nov 2 '17 at 19:59











        • I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

          – aziza
          Nov 2 '17 at 23:02











        • Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

          – Rémi Rousselet
          Nov 3 '17 at 1:20
















        23












        23








        23







        In flutter, there are a few way to deal with Async actions.



        An lazy way to do it can be using a modal. Which will block the user input, thus preventing any unwanted actions.
        This would require very little change to your code. Just modifying your _onLoading to something like this :



        void _onLoading() {
        showDialog(
        context: context,
        barrierDismissible: false,
        child: new Dialog(
        child: new Row(
        mainAxisSize: MainAxisSize.min,
        children: [
        new CircularProgressIndicator(),
        new Text("Loading"),
        ],
        ),
        ),
        );
        new Future.delayed(new Duration(seconds: 3), () {
        Navigator.pop(context); //pop dialog
        _login();
        });
        }


        The most ideal way to do it is using FutureBuilder and a stateful widget. Which is what you started.
        The trick is that, instead of having a boolean loading = false in your state, you can directly use a Future<MyUser> user



        And then pass it as argument to FutureBuilder, which will give you some info such as "hasData" or the instance of MyUser when completed.



        This would lead to something like this :



        @immutable
        class MyUser {
        final String name;

        MyUser(this.name);
        }

        class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
        return new MaterialApp(
        title: 'Flutter Demo',
        home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
        }
        }

        class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);

        final String title;

        @override
        _MyHomePageState createState() => new _MyHomePageState();
        }

        class _MyHomePageState extends State<MyHomePage> {
        Future<MyUser> user;

        void _logIn() {
        setState(() {
        user = new Future.delayed(const Duration(seconds: 3), () {
        return new MyUser("Toto");
        });
        });
        }

        Widget _buildForm(AsyncSnapshot<MyUser> snapshot) {
        var floatBtn = new RaisedButton(
        onPressed:
        snapshot.connectionState == ConnectionState.none ? _logIn : null,
        child: new Icon(Icons.save),
        );
        var action =
        snapshot.connectionState != ConnectionState.none && !snapshot.hasData
        ? new Stack(
        alignment: FractionalOffset.center,
        children: <Widget>[
        floatBtn,
        new CircularProgressIndicator(
        backgroundColor: Colors.red,
        ),
        ],
        )
        : floatBtn;

        return new ListView(
        padding: const EdgeInsets.all(15.0),
        children: <Widget>[
        new ListTile(
        title: new TextField(),
        ),
        new ListTile(
        title: new TextField(obscureText: true),
        ),
        new Center(child: action)
        ],
        );
        }

        @override
        Widget build(BuildContext context) {
        return new FutureBuilder(
        future: user,
        builder: (context, AsyncSnapshot<MyUser> snapshot) {
        if (snapshot.hasData) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Hello ${snapshot.data.name}"),
        ),
        );
        } else {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Connection"),
        ),
        body: _buildForm(snapshot),
        );
        }
        },
        );
        }
        }





        share|improve this answer













        In flutter, there are a few way to deal with Async actions.



        An lazy way to do it can be using a modal. Which will block the user input, thus preventing any unwanted actions.
        This would require very little change to your code. Just modifying your _onLoading to something like this :



        void _onLoading() {
        showDialog(
        context: context,
        barrierDismissible: false,
        child: new Dialog(
        child: new Row(
        mainAxisSize: MainAxisSize.min,
        children: [
        new CircularProgressIndicator(),
        new Text("Loading"),
        ],
        ),
        ),
        );
        new Future.delayed(new Duration(seconds: 3), () {
        Navigator.pop(context); //pop dialog
        _login();
        });
        }


        The most ideal way to do it is using FutureBuilder and a stateful widget. Which is what you started.
        The trick is that, instead of having a boolean loading = false in your state, you can directly use a Future<MyUser> user



        And then pass it as argument to FutureBuilder, which will give you some info such as "hasData" or the instance of MyUser when completed.



        This would lead to something like this :



        @immutable
        class MyUser {
        final String name;

        MyUser(this.name);
        }

        class MyApp extends StatelessWidget {
        // This widget is the root of your application.
        @override
        Widget build(BuildContext context) {
        return new MaterialApp(
        title: 'Flutter Demo',
        home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
        }
        }

        class MyHomePage extends StatefulWidget {
        MyHomePage({Key key, this.title}) : super(key: key);

        final String title;

        @override
        _MyHomePageState createState() => new _MyHomePageState();
        }

        class _MyHomePageState extends State<MyHomePage> {
        Future<MyUser> user;

        void _logIn() {
        setState(() {
        user = new Future.delayed(const Duration(seconds: 3), () {
        return new MyUser("Toto");
        });
        });
        }

        Widget _buildForm(AsyncSnapshot<MyUser> snapshot) {
        var floatBtn = new RaisedButton(
        onPressed:
        snapshot.connectionState == ConnectionState.none ? _logIn : null,
        child: new Icon(Icons.save),
        );
        var action =
        snapshot.connectionState != ConnectionState.none && !snapshot.hasData
        ? new Stack(
        alignment: FractionalOffset.center,
        children: <Widget>[
        floatBtn,
        new CircularProgressIndicator(
        backgroundColor: Colors.red,
        ),
        ],
        )
        : floatBtn;

        return new ListView(
        padding: const EdgeInsets.all(15.0),
        children: <Widget>[
        new ListTile(
        title: new TextField(),
        ),
        new ListTile(
        title: new TextField(obscureText: true),
        ),
        new Center(child: action)
        ],
        );
        }

        @override
        Widget build(BuildContext context) {
        return new FutureBuilder(
        future: user,
        builder: (context, AsyncSnapshot<MyUser> snapshot) {
        if (snapshot.hasData) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Hello ${snapshot.data.name}"),
        ),
        );
        } else {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text("Connection"),
        ),
        body: _buildForm(snapshot),
        );
        }
        },
        );
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 2 '17 at 12:40









        Rémi RousseletRémi Rousselet

        30.2k36793




        30.2k36793













        • Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

          – Ricardo Bocchi
          Nov 2 '17 at 16:49











        • a question off topic.. to each TextField I need a TextEditingController unique?

          – Ricardo Bocchi
          Nov 2 '17 at 17:36











        • @RicardoBocchi Yes

          – aziza
          Nov 2 '17 at 19:59











        • I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

          – aziza
          Nov 2 '17 at 23:02











        • Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

          – Rémi Rousselet
          Nov 3 '17 at 1:20





















        • Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

          – Ricardo Bocchi
          Nov 2 '17 at 16:49











        • a question off topic.. to each TextField I need a TextEditingController unique?

          – Ricardo Bocchi
          Nov 2 '17 at 17:36











        • @RicardoBocchi Yes

          – aziza
          Nov 2 '17 at 19:59











        • I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

          – aziza
          Nov 2 '17 at 23:02











        • Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

          – Rémi Rousselet
          Nov 3 '17 at 1:20



















        Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

        – Ricardo Bocchi
        Nov 2 '17 at 16:49





        Cool, both examples will be useful on login and other situations. Handler progress with dialog looks better than my version and FutureBuilder It's more elegant than my solution too. thanks for help!

        – Ricardo Bocchi
        Nov 2 '17 at 16:49













        a question off topic.. to each TextField I need a TextEditingController unique?

        – Ricardo Bocchi
        Nov 2 '17 at 17:36





        a question off topic.. to each TextField I need a TextEditingController unique?

        – Ricardo Bocchi
        Nov 2 '17 at 17:36













        @RicardoBocchi Yes

        – aziza
        Nov 2 '17 at 19:59





        @RicardoBocchi Yes

        – aziza
        Nov 2 '17 at 19:59













        I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

        – aziza
        Nov 2 '17 at 23:02





        I do not think the Dialog will work with actual example, it is confusing how will the user be redirected after the _login() is returned. Your second example though seems way more convenient. Well baked.

        – aziza
        Nov 2 '17 at 23:02













        Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

        – Rémi Rousselet
        Nov 3 '17 at 1:20







        Well, the Dialog is functional and requires very little modification to his original code. He could for example follow the dialog close with a Navigator.pushNamed("/home").

        – Rémi Rousselet
        Nov 3 '17 at 1:20















        13














        For me, one neat way to do this is to show a SnackBar at the bottom while the Signing-In process is taken place, this is a an example of what I mean:



        enter image description here



        Here is how to setup the SnackBar.



        Define a global key for your Scaffold



        final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();


        Add it to your Scaffold key attribute



        return new Scaffold(
        key: _scaffoldKey,
        .......


        My SignIn button onPressed callback:



        onPressed: () {
        _scaffoldKey.currentState.showSnackBar(
        new SnackBar(duration: new Duration(seconds: 4), content:
        new Row(
        children: <Widget>[
        new CircularProgressIndicator(),
        new Text(" Signing-In...")
        ],
        ),
        ));
        _handleSignIn()
        .whenComplete(() =>
        Navigator.of(context).pushNamed("/Home")
        );
        }


        It really depends on how you want to build your layout, and I am not sure what you have in mind.



        Edit



        You probably want it this way, I have used a Stack to achieve this result and just show or hide my indicator based on onPressed



        enter image description here



        class TestSignInView extends StatefulWidget {
        @override
        _TestSignInViewState createState() => new _TestSignInViewState();
        }


        class _TestSignInViewState extends State<TestSignInView> {
        bool _load = false;
        @override
        Widget build(BuildContext context) {
        Widget loadingIndicator =_load? new Container(
        color: Colors.grey[300],
        width: 70.0,
        height: 70.0,
        child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
        ):new Container();
        return new Scaffold(
        backgroundColor: Colors.white,
        body: new Stack(children: <Widget>[new Padding(
        padding: const EdgeInsets.symmetric(vertical: 50.0, horizontal: 20.0),
        child: new ListView(

        children: <Widget>[
        new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center
        ,children: <Widget>[
        new TextField(),
        new TextField(),

        new FlatButton(color:Colors.blue,child: new Text('Sign In'),
        onPressed: () {
        setState((){
        _load=true;
        });

        //Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new HomeTest()));
        }
        ),

        ],),],
        ),),
        new Align(child: loadingIndicator,alignment: FractionalOffset.center,),

        ],));
        }

        }





        share|improve this answer


























        • Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

          – Ricardo Bocchi
          Nov 2 '17 at 1:41











        • Hey, I do not understand your question?

          – aziza
          Nov 2 '17 at 1:46











        • In my code, when _loading change, all views are rebuild. Is that so?

          – Ricardo Bocchi
          Nov 2 '17 at 1:52






        • 1





          Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

          – Rémi Rousselet
          Nov 2 '17 at 9:12






        • 1





          Okey, let me bake something.

          – Rémi Rousselet
          Nov 2 '17 at 9:18
















        13














        For me, one neat way to do this is to show a SnackBar at the bottom while the Signing-In process is taken place, this is a an example of what I mean:



        enter image description here



        Here is how to setup the SnackBar.



        Define a global key for your Scaffold



        final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();


        Add it to your Scaffold key attribute



        return new Scaffold(
        key: _scaffoldKey,
        .......


        My SignIn button onPressed callback:



        onPressed: () {
        _scaffoldKey.currentState.showSnackBar(
        new SnackBar(duration: new Duration(seconds: 4), content:
        new Row(
        children: <Widget>[
        new CircularProgressIndicator(),
        new Text(" Signing-In...")
        ],
        ),
        ));
        _handleSignIn()
        .whenComplete(() =>
        Navigator.of(context).pushNamed("/Home")
        );
        }


        It really depends on how you want to build your layout, and I am not sure what you have in mind.



        Edit



        You probably want it this way, I have used a Stack to achieve this result and just show or hide my indicator based on onPressed



        enter image description here



        class TestSignInView extends StatefulWidget {
        @override
        _TestSignInViewState createState() => new _TestSignInViewState();
        }


        class _TestSignInViewState extends State<TestSignInView> {
        bool _load = false;
        @override
        Widget build(BuildContext context) {
        Widget loadingIndicator =_load? new Container(
        color: Colors.grey[300],
        width: 70.0,
        height: 70.0,
        child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
        ):new Container();
        return new Scaffold(
        backgroundColor: Colors.white,
        body: new Stack(children: <Widget>[new Padding(
        padding: const EdgeInsets.symmetric(vertical: 50.0, horizontal: 20.0),
        child: new ListView(

        children: <Widget>[
        new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center
        ,children: <Widget>[
        new TextField(),
        new TextField(),

        new FlatButton(color:Colors.blue,child: new Text('Sign In'),
        onPressed: () {
        setState((){
        _load=true;
        });

        //Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new HomeTest()));
        }
        ),

        ],),],
        ),),
        new Align(child: loadingIndicator,alignment: FractionalOffset.center,),

        ],));
        }

        }





        share|improve this answer


























        • Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

          – Ricardo Bocchi
          Nov 2 '17 at 1:41











        • Hey, I do not understand your question?

          – aziza
          Nov 2 '17 at 1:46











        • In my code, when _loading change, all views are rebuild. Is that so?

          – Ricardo Bocchi
          Nov 2 '17 at 1:52






        • 1





          Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

          – Rémi Rousselet
          Nov 2 '17 at 9:12






        • 1





          Okey, let me bake something.

          – Rémi Rousselet
          Nov 2 '17 at 9:18














        13












        13








        13







        For me, one neat way to do this is to show a SnackBar at the bottom while the Signing-In process is taken place, this is a an example of what I mean:



        enter image description here



        Here is how to setup the SnackBar.



        Define a global key for your Scaffold



        final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();


        Add it to your Scaffold key attribute



        return new Scaffold(
        key: _scaffoldKey,
        .......


        My SignIn button onPressed callback:



        onPressed: () {
        _scaffoldKey.currentState.showSnackBar(
        new SnackBar(duration: new Duration(seconds: 4), content:
        new Row(
        children: <Widget>[
        new CircularProgressIndicator(),
        new Text(" Signing-In...")
        ],
        ),
        ));
        _handleSignIn()
        .whenComplete(() =>
        Navigator.of(context).pushNamed("/Home")
        );
        }


        It really depends on how you want to build your layout, and I am not sure what you have in mind.



        Edit



        You probably want it this way, I have used a Stack to achieve this result and just show or hide my indicator based on onPressed



        enter image description here



        class TestSignInView extends StatefulWidget {
        @override
        _TestSignInViewState createState() => new _TestSignInViewState();
        }


        class _TestSignInViewState extends State<TestSignInView> {
        bool _load = false;
        @override
        Widget build(BuildContext context) {
        Widget loadingIndicator =_load? new Container(
        color: Colors.grey[300],
        width: 70.0,
        height: 70.0,
        child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
        ):new Container();
        return new Scaffold(
        backgroundColor: Colors.white,
        body: new Stack(children: <Widget>[new Padding(
        padding: const EdgeInsets.symmetric(vertical: 50.0, horizontal: 20.0),
        child: new ListView(

        children: <Widget>[
        new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center
        ,children: <Widget>[
        new TextField(),
        new TextField(),

        new FlatButton(color:Colors.blue,child: new Text('Sign In'),
        onPressed: () {
        setState((){
        _load=true;
        });

        //Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new HomeTest()));
        }
        ),

        ],),],
        ),),
        new Align(child: loadingIndicator,alignment: FractionalOffset.center,),

        ],));
        }

        }





        share|improve this answer















        For me, one neat way to do this is to show a SnackBar at the bottom while the Signing-In process is taken place, this is a an example of what I mean:



        enter image description here



        Here is how to setup the SnackBar.



        Define a global key for your Scaffold



        final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();


        Add it to your Scaffold key attribute



        return new Scaffold(
        key: _scaffoldKey,
        .......


        My SignIn button onPressed callback:



        onPressed: () {
        _scaffoldKey.currentState.showSnackBar(
        new SnackBar(duration: new Duration(seconds: 4), content:
        new Row(
        children: <Widget>[
        new CircularProgressIndicator(),
        new Text(" Signing-In...")
        ],
        ),
        ));
        _handleSignIn()
        .whenComplete(() =>
        Navigator.of(context).pushNamed("/Home")
        );
        }


        It really depends on how you want to build your layout, and I am not sure what you have in mind.



        Edit



        You probably want it this way, I have used a Stack to achieve this result and just show or hide my indicator based on onPressed



        enter image description here



        class TestSignInView extends StatefulWidget {
        @override
        _TestSignInViewState createState() => new _TestSignInViewState();
        }


        class _TestSignInViewState extends State<TestSignInView> {
        bool _load = false;
        @override
        Widget build(BuildContext context) {
        Widget loadingIndicator =_load? new Container(
        color: Colors.grey[300],
        width: 70.0,
        height: 70.0,
        child: new Padding(padding: const EdgeInsets.all(5.0),child: new Center(child: new CircularProgressIndicator())),
        ):new Container();
        return new Scaffold(
        backgroundColor: Colors.white,
        body: new Stack(children: <Widget>[new Padding(
        padding: const EdgeInsets.symmetric(vertical: 50.0, horizontal: 20.0),
        child: new ListView(

        children: <Widget>[
        new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center
        ,children: <Widget>[
        new TextField(),
        new TextField(),

        new FlatButton(color:Colors.blue,child: new Text('Sign In'),
        onPressed: () {
        setState((){
        _load=true;
        });

        //Navigator.of(context).push(new MaterialPageRoute(builder: (_)=>new HomeTest()));
        }
        ),

        ],),],
        ),),
        new Align(child: loadingIndicator,alignment: FractionalOffset.center,),

        ],));
        }

        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 2 '17 at 1:29

























        answered Nov 2 '17 at 0:43









        azizaaziza

        8,18222847




        8,18222847













        • Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

          – Ricardo Bocchi
          Nov 2 '17 at 1:41











        • Hey, I do not understand your question?

          – aziza
          Nov 2 '17 at 1:46











        • In my code, when _loading change, all views are rebuild. Is that so?

          – Ricardo Bocchi
          Nov 2 '17 at 1:52






        • 1





          Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

          – Rémi Rousselet
          Nov 2 '17 at 9:12






        • 1





          Okey, let me bake something.

          – Rémi Rousselet
          Nov 2 '17 at 9:18



















        • Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

          – Ricardo Bocchi
          Nov 2 '17 at 1:41











        • Hey, I do not understand your question?

          – aziza
          Nov 2 '17 at 1:46











        • In my code, when _loading change, all views are rebuild. Is that so?

          – Ricardo Bocchi
          Nov 2 '17 at 1:52






        • 1





          Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

          – Rémi Rousselet
          Nov 2 '17 at 9:12






        • 1





          Okey, let me bake something.

          – Rémi Rousselet
          Nov 2 '17 at 9:18

















        Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

        – Ricardo Bocchi
        Nov 2 '17 at 1:41





        Hi, that's what I wanted to do, but I was not getting the layout I needed. Stack is the answer. About StatefulWidget, is it correct build all view when progress state change?

        – Ricardo Bocchi
        Nov 2 '17 at 1:41













        Hey, I do not understand your question?

        – aziza
        Nov 2 '17 at 1:46





        Hey, I do not understand your question?

        – aziza
        Nov 2 '17 at 1:46













        In my code, when _loading change, all views are rebuild. Is that so?

        – Ricardo Bocchi
        Nov 2 '17 at 1:52





        In my code, when _loading change, all views are rebuild. Is that so?

        – Ricardo Bocchi
        Nov 2 '17 at 1:52




        1




        1





        Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

        – Rémi Rousselet
        Nov 2 '17 at 9:12





        Using a modal is probably much easier and more intuitive at the same time. You can just push a loading dialog at the beggining or your request, and pop it when finished. It also has the advantage of preventing further user input.

        – Rémi Rousselet
        Nov 2 '17 at 9:12




        1




        1





        Okey, let me bake something.

        – Rémi Rousselet
        Nov 2 '17 at 9:18





        Okey, let me bake something.

        – Rémi Rousselet
        Nov 2 '17 at 9:18











        6














        1. Without plugin



            class IndiSampleState extends State<ProgHudPage> {
        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('Demo'),
        ),
        body: Center(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async {
        showDialog(
        context: context,
        builder: (BuildContext context) {
        return Center(child: CircularProgressIndicator(),);
        });
        await loginAction();
        Navigator.pop(context);
        },
        ),
        ));
        }

        Future<bool> loginAction() async {
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }


        2. With plugin



        check this plugin progress_hud



        add the dependency in the pubspec.yaml file



        dev_dependencies:
        progress_hud:


        import the package



        import 'package:progress_hud/progress_hud.dart';


        Sample code is given below to show and hide the indicator



        class ProgHudPage extends StatefulWidget {
        @override
        _ProgHudPageState createState() => _ProgHudPageState();
        }

        class _ProgHudPageState extends State<ProgHudPage> {
        ProgressHUD _progressHUD;
        @override
        void initState() {
        _progressHUD = new ProgressHUD(
        backgroundColor: Colors.black12,
        color: Colors.white,
        containerColor: Colors.blue,
        borderRadius: 5.0,
        loading: false,
        text: 'Loading...',
        );
        super.initState();
        }

        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('ProgressHUD Demo'),
        ),
        body: new Stack(
        children: <Widget>[
        _progressHUD,
        new Positioned(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async{
        _progressHUD.state.show();
        await loginAction();
        _progressHUD.state.dismiss();
        },
        ),
        bottom: 30.0,
        right: 10.0)
        ],
        ));
        }

        Future<bool> loginAction()async{
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }





        share|improve this answer





















        • 3





          Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

          – Vladtn
          Apr 4 '18 at 10:19






        • 1





          Its not working.

          – prashant fepale
          Jul 4 '18 at 7:57






        • 2





          the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

          – prashant0205
          Jul 23 '18 at 10:25











        • Should you really add this as a Dev Dependency?

          – George
          Dec 25 '18 at 14:39











        • This plugin is not working!!!

          – Idee
          Jan 3 at 15:35
















        6














        1. Without plugin



            class IndiSampleState extends State<ProgHudPage> {
        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('Demo'),
        ),
        body: Center(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async {
        showDialog(
        context: context,
        builder: (BuildContext context) {
        return Center(child: CircularProgressIndicator(),);
        });
        await loginAction();
        Navigator.pop(context);
        },
        ),
        ));
        }

        Future<bool> loginAction() async {
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }


        2. With plugin



        check this plugin progress_hud



        add the dependency in the pubspec.yaml file



        dev_dependencies:
        progress_hud:


        import the package



        import 'package:progress_hud/progress_hud.dart';


        Sample code is given below to show and hide the indicator



        class ProgHudPage extends StatefulWidget {
        @override
        _ProgHudPageState createState() => _ProgHudPageState();
        }

        class _ProgHudPageState extends State<ProgHudPage> {
        ProgressHUD _progressHUD;
        @override
        void initState() {
        _progressHUD = new ProgressHUD(
        backgroundColor: Colors.black12,
        color: Colors.white,
        containerColor: Colors.blue,
        borderRadius: 5.0,
        loading: false,
        text: 'Loading...',
        );
        super.initState();
        }

        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('ProgressHUD Demo'),
        ),
        body: new Stack(
        children: <Widget>[
        _progressHUD,
        new Positioned(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async{
        _progressHUD.state.show();
        await loginAction();
        _progressHUD.state.dismiss();
        },
        ),
        bottom: 30.0,
        right: 10.0)
        ],
        ));
        }

        Future<bool> loginAction()async{
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }





        share|improve this answer





















        • 3





          Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

          – Vladtn
          Apr 4 '18 at 10:19






        • 1





          Its not working.

          – prashant fepale
          Jul 4 '18 at 7:57






        • 2





          the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

          – prashant0205
          Jul 23 '18 at 10:25











        • Should you really add this as a Dev Dependency?

          – George
          Dec 25 '18 at 14:39











        • This plugin is not working!!!

          – Idee
          Jan 3 at 15:35














        6












        6








        6







        1. Without plugin



            class IndiSampleState extends State<ProgHudPage> {
        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('Demo'),
        ),
        body: Center(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async {
        showDialog(
        context: context,
        builder: (BuildContext context) {
        return Center(child: CircularProgressIndicator(),);
        });
        await loginAction();
        Navigator.pop(context);
        },
        ),
        ));
        }

        Future<bool> loginAction() async {
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }


        2. With plugin



        check this plugin progress_hud



        add the dependency in the pubspec.yaml file



        dev_dependencies:
        progress_hud:


        import the package



        import 'package:progress_hud/progress_hud.dart';


        Sample code is given below to show and hide the indicator



        class ProgHudPage extends StatefulWidget {
        @override
        _ProgHudPageState createState() => _ProgHudPageState();
        }

        class _ProgHudPageState extends State<ProgHudPage> {
        ProgressHUD _progressHUD;
        @override
        void initState() {
        _progressHUD = new ProgressHUD(
        backgroundColor: Colors.black12,
        color: Colors.white,
        containerColor: Colors.blue,
        borderRadius: 5.0,
        loading: false,
        text: 'Loading...',
        );
        super.initState();
        }

        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('ProgressHUD Demo'),
        ),
        body: new Stack(
        children: <Widget>[
        _progressHUD,
        new Positioned(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async{
        _progressHUD.state.show();
        await loginAction();
        _progressHUD.state.dismiss();
        },
        ),
        bottom: 30.0,
        right: 10.0)
        ],
        ));
        }

        Future<bool> loginAction()async{
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }





        share|improve this answer















        1. Without plugin



            class IndiSampleState extends State<ProgHudPage> {
        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('Demo'),
        ),
        body: Center(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async {
        showDialog(
        context: context,
        builder: (BuildContext context) {
        return Center(child: CircularProgressIndicator(),);
        });
        await loginAction();
        Navigator.pop(context);
        },
        ),
        ));
        }

        Future<bool> loginAction() async {
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }


        2. With plugin



        check this plugin progress_hud



        add the dependency in the pubspec.yaml file



        dev_dependencies:
        progress_hud:


        import the package



        import 'package:progress_hud/progress_hud.dart';


        Sample code is given below to show and hide the indicator



        class ProgHudPage extends StatefulWidget {
        @override
        _ProgHudPageState createState() => _ProgHudPageState();
        }

        class _ProgHudPageState extends State<ProgHudPage> {
        ProgressHUD _progressHUD;
        @override
        void initState() {
        _progressHUD = new ProgressHUD(
        backgroundColor: Colors.black12,
        color: Colors.white,
        containerColor: Colors.blue,
        borderRadius: 5.0,
        loading: false,
        text: 'Loading...',
        );
        super.initState();
        }

        @override
        Widget build(BuildContext context) {
        return new Scaffold(
        appBar: new AppBar(
        title: new Text('ProgressHUD Demo'),
        ),
        body: new Stack(
        children: <Widget>[
        _progressHUD,
        new Positioned(
        child: RaisedButton(
        color: Colors.blueAccent,
        child: Text('Login'),
        onPressed: () async{
        _progressHUD.state.show();
        await loginAction();
        _progressHUD.state.dismiss();
        },
        ),
        bottom: 30.0,
        right: 10.0)
        ],
        ));
        }

        Future<bool> loginAction()async{
        //replace the below line of code with your login request
        await new Future.delayed(const Duration(seconds: 2));
        return true;
        }
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 30 at 17:05

























        answered Mar 21 '18 at 9:40









        Shyju MShyju M

        1,1171018




        1,1171018








        • 3





          Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

          – Vladtn
          Apr 4 '18 at 10:19






        • 1





          Its not working.

          – prashant fepale
          Jul 4 '18 at 7:57






        • 2





          the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

          – prashant0205
          Jul 23 '18 at 10:25











        • Should you really add this as a Dev Dependency?

          – George
          Dec 25 '18 at 14:39











        • This plugin is not working!!!

          – Idee
          Jan 3 at 15:35














        • 3





          Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

          – Vladtn
          Apr 4 '18 at 10:19






        • 1





          Its not working.

          – prashant fepale
          Jul 4 '18 at 7:57






        • 2





          the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

          – prashant0205
          Jul 23 '18 at 10:25











        • Should you really add this as a Dev Dependency?

          – George
          Dec 25 '18 at 14:39











        • This plugin is not working!!!

          – Idee
          Jan 3 at 15:35








        3




        3





        Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

        – Vladtn
        Apr 4 '18 at 10:19





        Don't vote this down, some people don't want to handle the nitty-gritty details of UI and am one of them so this plugin comes in handy

        – Vladtn
        Apr 4 '18 at 10:19




        1




        1





        Its not working.

        – prashant fepale
        Jul 4 '18 at 7:57





        Its not working.

        – prashant fepale
        Jul 4 '18 at 7:57




        2




        2





        the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

        – prashant0205
        Jul 23 '18 at 10:25





        the progress bar in api is fair enough adding dependency increases build size. already flutter build is excessive.

        – prashant0205
        Jul 23 '18 at 10:25













        Should you really add this as a Dev Dependency?

        – George
        Dec 25 '18 at 14:39





        Should you really add this as a Dev Dependency?

        – George
        Dec 25 '18 at 14:39













        This plugin is not working!!!

        – Idee
        Jan 3 at 15:35





        This plugin is not working!!!

        – Idee
        Jan 3 at 15:35











        5














        Create a bool isLoading and set it to false. With the help of ternary operator, When user clicks on login button set state of isLoading to true. You will get circular loading indicator in place of login button



         isLoading ? new PrimaryButton(
        key: new Key('login'),
        text: 'Login',
        height: 44.0,
        onPressed: SetState((){isLoading = ture;}))
        : Center(
        child: CircularProgressIndicator(),
        ),


        You can see Screenshots how it looks while before login clicked
        enter image description here



        After login clicked
        enter image description here



        In mean time you can run login process and login user. If user credentials are wrong then again you will setState of isLoading to false, such that loading indicator will become invisible and login button visible to user.
        By the way, primaryButton used in code is my custom button. You can do same with OnPressed in button.






        share|improve this answer
























        • That's actually pretty smart! No need to handle double click etc. Thanks.

          – Benobab
          Feb 2 at 21:03
















        5














        Create a bool isLoading and set it to false. With the help of ternary operator, When user clicks on login button set state of isLoading to true. You will get circular loading indicator in place of login button



         isLoading ? new PrimaryButton(
        key: new Key('login'),
        text: 'Login',
        height: 44.0,
        onPressed: SetState((){isLoading = ture;}))
        : Center(
        child: CircularProgressIndicator(),
        ),


        You can see Screenshots how it looks while before login clicked
        enter image description here



        After login clicked
        enter image description here



        In mean time you can run login process and login user. If user credentials are wrong then again you will setState of isLoading to false, such that loading indicator will become invisible and login button visible to user.
        By the way, primaryButton used in code is my custom button. You can do same with OnPressed in button.






        share|improve this answer
























        • That's actually pretty smart! No need to handle double click etc. Thanks.

          – Benobab
          Feb 2 at 21:03














        5












        5








        5







        Create a bool isLoading and set it to false. With the help of ternary operator, When user clicks on login button set state of isLoading to true. You will get circular loading indicator in place of login button



         isLoading ? new PrimaryButton(
        key: new Key('login'),
        text: 'Login',
        height: 44.0,
        onPressed: SetState((){isLoading = ture;}))
        : Center(
        child: CircularProgressIndicator(),
        ),


        You can see Screenshots how it looks while before login clicked
        enter image description here



        After login clicked
        enter image description here



        In mean time you can run login process and login user. If user credentials are wrong then again you will setState of isLoading to false, such that loading indicator will become invisible and login button visible to user.
        By the way, primaryButton used in code is my custom button. You can do same with OnPressed in button.






        share|improve this answer













        Create a bool isLoading and set it to false. With the help of ternary operator, When user clicks on login button set state of isLoading to true. You will get circular loading indicator in place of login button



         isLoading ? new PrimaryButton(
        key: new Key('login'),
        text: 'Login',
        height: 44.0,
        onPressed: SetState((){isLoading = ture;}))
        : Center(
        child: CircularProgressIndicator(),
        ),


        You can see Screenshots how it looks while before login clicked
        enter image description here



        After login clicked
        enter image description here



        In mean time you can run login process and login user. If user credentials are wrong then again you will setState of isLoading to false, such that loading indicator will become invisible and login button visible to user.
        By the way, primaryButton used in code is my custom button. You can do same with OnPressed in button.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 9:57









        Harsha pulikolluHarsha pulikollu

        17218




        17218













        • That's actually pretty smart! No need to handle double click etc. Thanks.

          – Benobab
          Feb 2 at 21:03



















        • That's actually pretty smart! No need to handle double click etc. Thanks.

          – Benobab
          Feb 2 at 21:03

















        That's actually pretty smart! No need to handle double click etc. Thanks.

        – Benobab
        Feb 2 at 21:03





        That's actually pretty smart! No need to handle double click etc. Thanks.

        – Benobab
        Feb 2 at 21:03











        3














        I took the following approach, which uses a simple modal progress indicator widget that wraps whatever you want to make modal during an async call.



        The example in the package also addresses how to handle form validation while making async calls to validate the form (see flutter/issues/9688 for details of this problem). For example, without leaving the form, this async form validation method can be used to validate a new user name against existing names in a database while signing up.



        https://pub.dartlang.org/packages/modal_progress_hud



        Here is the demo of the example provided with the package (with source code):



        async form validation with modal progress indicator



        Example could be adapted to other modal progress indicator behaviour (like different animations, additional text in modal, etc..).






        share|improve this answer




























          3














          I took the following approach, which uses a simple modal progress indicator widget that wraps whatever you want to make modal during an async call.



          The example in the package also addresses how to handle form validation while making async calls to validate the form (see flutter/issues/9688 for details of this problem). For example, without leaving the form, this async form validation method can be used to validate a new user name against existing names in a database while signing up.



          https://pub.dartlang.org/packages/modal_progress_hud



          Here is the demo of the example provided with the package (with source code):



          async form validation with modal progress indicator



          Example could be adapted to other modal progress indicator behaviour (like different animations, additional text in modal, etc..).






          share|improve this answer


























            3












            3








            3







            I took the following approach, which uses a simple modal progress indicator widget that wraps whatever you want to make modal during an async call.



            The example in the package also addresses how to handle form validation while making async calls to validate the form (see flutter/issues/9688 for details of this problem). For example, without leaving the form, this async form validation method can be used to validate a new user name against existing names in a database while signing up.



            https://pub.dartlang.org/packages/modal_progress_hud



            Here is the demo of the example provided with the package (with source code):



            async form validation with modal progress indicator



            Example could be adapted to other modal progress indicator behaviour (like different animations, additional text in modal, etc..).






            share|improve this answer













            I took the following approach, which uses a simple modal progress indicator widget that wraps whatever you want to make modal during an async call.



            The example in the package also addresses how to handle form validation while making async calls to validate the form (see flutter/issues/9688 for details of this problem). For example, without leaving the form, this async form validation method can be used to validate a new user name against existing names in a database while signing up.



            https://pub.dartlang.org/packages/modal_progress_hud



            Here is the demo of the example provided with the package (with source code):



            async form validation with modal progress indicator



            Example could be adapted to other modal progress indicator behaviour (like different animations, additional text in modal, etc..).







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 12 '18 at 13:59









            mmccabemmccabe

            1,1001016




            1,1001016























                0














                This is my solution with stack



                import 'package:flutter/material.dart';
                import 'package:shared_preferences/shared_preferences.dart';
                import 'dart:async';

                final themeColor = new Color(0xfff5a623);
                final primaryColor = new Color(0xff203152);
                final greyColor = new Color(0xffaeaeae);
                final greyColor2 = new Color(0xffE8E8E8);

                class LoadindScreen extends StatefulWidget {
                LoadindScreen({Key key, this.title}) : super(key: key);
                final String title;
                @override
                LoginScreenState createState() => new LoginScreenState();
                }

                class LoginScreenState extends State<LoadindScreen> {
                SharedPreferences prefs;

                bool isLoading = false;

                Future<Null> handleSignIn() async {
                setState(() {
                isLoading = true;
                });
                prefs = await SharedPreferences.getInstance();
                var isLoadingFuture = Future.delayed(const Duration(seconds: 3), () {
                return false;
                });
                isLoadingFuture.then((response) {
                setState(() {
                isLoading = response;
                });
                });
                }

                @override
                Widget build(BuildContext context) {
                return Scaffold(
                appBar: AppBar(
                title: Text(
                widget.title,
                style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
                ),
                centerTitle: true,
                ),
                body: Stack(
                children: <Widget>[
                Center(
                child: FlatButton(
                onPressed: handleSignIn,
                child: Text(
                'SIGN IN WITH GOOGLE',
                style: TextStyle(fontSize: 16.0),
                ),
                color: Color(0xffdd4b39),
                highlightColor: Color(0xffff7f7f),
                splashColor: Colors.transparent,
                textColor: Colors.white,
                padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
                ),

                // Loading
                Positioned(
                child: isLoading
                ? Container(
                child: Center(
                child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(themeColor),
                ),
                ),
                color: Colors.white.withOpacity(0.8),
                )
                : Container(),
                ),
                ],
                ));
                }
                }





                share|improve this answer




























                  0














                  This is my solution with stack



                  import 'package:flutter/material.dart';
                  import 'package:shared_preferences/shared_preferences.dart';
                  import 'dart:async';

                  final themeColor = new Color(0xfff5a623);
                  final primaryColor = new Color(0xff203152);
                  final greyColor = new Color(0xffaeaeae);
                  final greyColor2 = new Color(0xffE8E8E8);

                  class LoadindScreen extends StatefulWidget {
                  LoadindScreen({Key key, this.title}) : super(key: key);
                  final String title;
                  @override
                  LoginScreenState createState() => new LoginScreenState();
                  }

                  class LoginScreenState extends State<LoadindScreen> {
                  SharedPreferences prefs;

                  bool isLoading = false;

                  Future<Null> handleSignIn() async {
                  setState(() {
                  isLoading = true;
                  });
                  prefs = await SharedPreferences.getInstance();
                  var isLoadingFuture = Future.delayed(const Duration(seconds: 3), () {
                  return false;
                  });
                  isLoadingFuture.then((response) {
                  setState(() {
                  isLoading = response;
                  });
                  });
                  }

                  @override
                  Widget build(BuildContext context) {
                  return Scaffold(
                  appBar: AppBar(
                  title: Text(
                  widget.title,
                  style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
                  ),
                  centerTitle: true,
                  ),
                  body: Stack(
                  children: <Widget>[
                  Center(
                  child: FlatButton(
                  onPressed: handleSignIn,
                  child: Text(
                  'SIGN IN WITH GOOGLE',
                  style: TextStyle(fontSize: 16.0),
                  ),
                  color: Color(0xffdd4b39),
                  highlightColor: Color(0xffff7f7f),
                  splashColor: Colors.transparent,
                  textColor: Colors.white,
                  padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
                  ),

                  // Loading
                  Positioned(
                  child: isLoading
                  ? Container(
                  child: Center(
                  child: CircularProgressIndicator(
                  valueColor: AlwaysStoppedAnimation<Color>(themeColor),
                  ),
                  ),
                  color: Colors.white.withOpacity(0.8),
                  )
                  : Container(),
                  ),
                  ],
                  ));
                  }
                  }





                  share|improve this answer


























                    0












                    0








                    0







                    This is my solution with stack



                    import 'package:flutter/material.dart';
                    import 'package:shared_preferences/shared_preferences.dart';
                    import 'dart:async';

                    final themeColor = new Color(0xfff5a623);
                    final primaryColor = new Color(0xff203152);
                    final greyColor = new Color(0xffaeaeae);
                    final greyColor2 = new Color(0xffE8E8E8);

                    class LoadindScreen extends StatefulWidget {
                    LoadindScreen({Key key, this.title}) : super(key: key);
                    final String title;
                    @override
                    LoginScreenState createState() => new LoginScreenState();
                    }

                    class LoginScreenState extends State<LoadindScreen> {
                    SharedPreferences prefs;

                    bool isLoading = false;

                    Future<Null> handleSignIn() async {
                    setState(() {
                    isLoading = true;
                    });
                    prefs = await SharedPreferences.getInstance();
                    var isLoadingFuture = Future.delayed(const Duration(seconds: 3), () {
                    return false;
                    });
                    isLoadingFuture.then((response) {
                    setState(() {
                    isLoading = response;
                    });
                    });
                    }

                    @override
                    Widget build(BuildContext context) {
                    return Scaffold(
                    appBar: AppBar(
                    title: Text(
                    widget.title,
                    style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
                    ),
                    centerTitle: true,
                    ),
                    body: Stack(
                    children: <Widget>[
                    Center(
                    child: FlatButton(
                    onPressed: handleSignIn,
                    child: Text(
                    'SIGN IN WITH GOOGLE',
                    style: TextStyle(fontSize: 16.0),
                    ),
                    color: Color(0xffdd4b39),
                    highlightColor: Color(0xffff7f7f),
                    splashColor: Colors.transparent,
                    textColor: Colors.white,
                    padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
                    ),

                    // Loading
                    Positioned(
                    child: isLoading
                    ? Container(
                    child: Center(
                    child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation<Color>(themeColor),
                    ),
                    ),
                    color: Colors.white.withOpacity(0.8),
                    )
                    : Container(),
                    ),
                    ],
                    ));
                    }
                    }





                    share|improve this answer













                    This is my solution with stack



                    import 'package:flutter/material.dart';
                    import 'package:shared_preferences/shared_preferences.dart';
                    import 'dart:async';

                    final themeColor = new Color(0xfff5a623);
                    final primaryColor = new Color(0xff203152);
                    final greyColor = new Color(0xffaeaeae);
                    final greyColor2 = new Color(0xffE8E8E8);

                    class LoadindScreen extends StatefulWidget {
                    LoadindScreen({Key key, this.title}) : super(key: key);
                    final String title;
                    @override
                    LoginScreenState createState() => new LoginScreenState();
                    }

                    class LoginScreenState extends State<LoadindScreen> {
                    SharedPreferences prefs;

                    bool isLoading = false;

                    Future<Null> handleSignIn() async {
                    setState(() {
                    isLoading = true;
                    });
                    prefs = await SharedPreferences.getInstance();
                    var isLoadingFuture = Future.delayed(const Duration(seconds: 3), () {
                    return false;
                    });
                    isLoadingFuture.then((response) {
                    setState(() {
                    isLoading = response;
                    });
                    });
                    }

                    @override
                    Widget build(BuildContext context) {
                    return Scaffold(
                    appBar: AppBar(
                    title: Text(
                    widget.title,
                    style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
                    ),
                    centerTitle: true,
                    ),
                    body: Stack(
                    children: <Widget>[
                    Center(
                    child: FlatButton(
                    onPressed: handleSignIn,
                    child: Text(
                    'SIGN IN WITH GOOGLE',
                    style: TextStyle(fontSize: 16.0),
                    ),
                    color: Color(0xffdd4b39),
                    highlightColor: Color(0xffff7f7f),
                    splashColor: Colors.transparent,
                    textColor: Colors.white,
                    padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0)),
                    ),

                    // Loading
                    Positioned(
                    child: isLoading
                    ? Container(
                    child: Center(
                    child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation<Color>(themeColor),
                    ),
                    ),
                    color: Colors.white.withOpacity(0.8),
                    )
                    : Container(),
                    ),
                    ],
                    ));
                    }
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 27 '18 at 3:56









                    kokemomukekokemomuke

                    344510




                    344510























                        0














                        You can use FutureBuilder widget instead. This takes an argument which must be a Future. Then you can use a snapshot which is the state at the time being of the async call when loging in, once it ends the state of the async function return will be updated and the future builder will rebuild itself so you can then ask for the new state.



                        FutureBuilder(
                        future: myFutureFunction(),
                        builder: (context, AsyncSnapshot<List<item>> snapshot) {
                        if (!snapshot.hasData) {
                        return Center(
                        child: CircularProgressIndicator(),
                        );
                        } else {
                        //Send the user to the next page.
                        },
                        );


                        Here you have an example on how to build a Future



                        Future<void> myFutureFunction() async{
                        await callToApi();}





                        share|improve this answer




























                          0














                          You can use FutureBuilder widget instead. This takes an argument which must be a Future. Then you can use a snapshot which is the state at the time being of the async call when loging in, once it ends the state of the async function return will be updated and the future builder will rebuild itself so you can then ask for the new state.



                          FutureBuilder(
                          future: myFutureFunction(),
                          builder: (context, AsyncSnapshot<List<item>> snapshot) {
                          if (!snapshot.hasData) {
                          return Center(
                          child: CircularProgressIndicator(),
                          );
                          } else {
                          //Send the user to the next page.
                          },
                          );


                          Here you have an example on how to build a Future



                          Future<void> myFutureFunction() async{
                          await callToApi();}





                          share|improve this answer


























                            0












                            0








                            0







                            You can use FutureBuilder widget instead. This takes an argument which must be a Future. Then you can use a snapshot which is the state at the time being of the async call when loging in, once it ends the state of the async function return will be updated and the future builder will rebuild itself so you can then ask for the new state.



                            FutureBuilder(
                            future: myFutureFunction(),
                            builder: (context, AsyncSnapshot<List<item>> snapshot) {
                            if (!snapshot.hasData) {
                            return Center(
                            child: CircularProgressIndicator(),
                            );
                            } else {
                            //Send the user to the next page.
                            },
                            );


                            Here you have an example on how to build a Future



                            Future<void> myFutureFunction() async{
                            await callToApi();}





                            share|improve this answer













                            You can use FutureBuilder widget instead. This takes an argument which must be a Future. Then you can use a snapshot which is the state at the time being of the async call when loging in, once it ends the state of the async function return will be updated and the future builder will rebuild itself so you can then ask for the new state.



                            FutureBuilder(
                            future: myFutureFunction(),
                            builder: (context, AsyncSnapshot<List<item>> snapshot) {
                            if (!snapshot.hasData) {
                            return Center(
                            child: CircularProgressIndicator(),
                            );
                            } else {
                            //Send the user to the next page.
                            },
                            );


                            Here you have an example on how to build a Future



                            Future<void> myFutureFunction() async{
                            await callToApi();}






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 26 '18 at 19:46









                            MatiasMatias

                            342312




                            342312























                                0














                                class Loader extends StatefulWidget {
                                @override
                                State createState() => LoaderState();
                                }

                                class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
                                AnimationController controller;
                                Animation<double> animation;

                                @override
                                void initState() {
                                super.initState();
                                controller = AnimationController(
                                duration: Duration(milliseconds: 1200), vsync: this);
                                animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
                                animation.addListener(() {
                                this.setState(() {});
                                });
                                animation.addStatusListener((AnimationStatus status) {});
                                controller.repeat();
                                }

                                @override
                                void dispose() {
                                controller.dispose();
                                super.dispose();
                                }

                                @override
                                Widget build(BuildContext context) {
                                return Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 100.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue[300],
                                height: 3.0,
                                width: animation.value * 75.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 50.0,
                                )
                                ],
                                );
                                }
                                }


                                Expanded(
                                child: Padding(
                                padding:
                                EdgeInsets.only(left: 20.0, right: 5.0, top:20.0),
                                child: GestureDetector(
                                onTap: () {
                                Navigator.push(
                                context,
                                MaterialPageRoute(
                                builder: (context) => FirstScreen()));
                                },
                                child: Container(
                                alignment: Alignment.center,
                                height: 45.0,
                                decoration: BoxDecoration(
                                color: Color(0xFF1976D2),
                                borderRadius: BorderRadius.circular(9.0)),
                                child: Text('Login',
                                style: TextStyle(
                                fontSize: 20.0, color: Colors.white))),
                                ),
                                ),
                                ),





                                share|improve this answer
























                                • How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

                                  – Max Zubko
                                  Dec 24 '18 at 21:01
















                                0














                                class Loader extends StatefulWidget {
                                @override
                                State createState() => LoaderState();
                                }

                                class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
                                AnimationController controller;
                                Animation<double> animation;

                                @override
                                void initState() {
                                super.initState();
                                controller = AnimationController(
                                duration: Duration(milliseconds: 1200), vsync: this);
                                animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
                                animation.addListener(() {
                                this.setState(() {});
                                });
                                animation.addStatusListener((AnimationStatus status) {});
                                controller.repeat();
                                }

                                @override
                                void dispose() {
                                controller.dispose();
                                super.dispose();
                                }

                                @override
                                Widget build(BuildContext context) {
                                return Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 100.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue[300],
                                height: 3.0,
                                width: animation.value * 75.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 50.0,
                                )
                                ],
                                );
                                }
                                }


                                Expanded(
                                child: Padding(
                                padding:
                                EdgeInsets.only(left: 20.0, right: 5.0, top:20.0),
                                child: GestureDetector(
                                onTap: () {
                                Navigator.push(
                                context,
                                MaterialPageRoute(
                                builder: (context) => FirstScreen()));
                                },
                                child: Container(
                                alignment: Alignment.center,
                                height: 45.0,
                                decoration: BoxDecoration(
                                color: Color(0xFF1976D2),
                                borderRadius: BorderRadius.circular(9.0)),
                                child: Text('Login',
                                style: TextStyle(
                                fontSize: 20.0, color: Colors.white))),
                                ),
                                ),
                                ),





                                share|improve this answer
























                                • How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

                                  – Max Zubko
                                  Dec 24 '18 at 21:01














                                0












                                0








                                0







                                class Loader extends StatefulWidget {
                                @override
                                State createState() => LoaderState();
                                }

                                class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
                                AnimationController controller;
                                Animation<double> animation;

                                @override
                                void initState() {
                                super.initState();
                                controller = AnimationController(
                                duration: Duration(milliseconds: 1200), vsync: this);
                                animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
                                animation.addListener(() {
                                this.setState(() {});
                                });
                                animation.addStatusListener((AnimationStatus status) {});
                                controller.repeat();
                                }

                                @override
                                void dispose() {
                                controller.dispose();
                                super.dispose();
                                }

                                @override
                                Widget build(BuildContext context) {
                                return Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 100.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue[300],
                                height: 3.0,
                                width: animation.value * 75.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 50.0,
                                )
                                ],
                                );
                                }
                                }


                                Expanded(
                                child: Padding(
                                padding:
                                EdgeInsets.only(left: 20.0, right: 5.0, top:20.0),
                                child: GestureDetector(
                                onTap: () {
                                Navigator.push(
                                context,
                                MaterialPageRoute(
                                builder: (context) => FirstScreen()));
                                },
                                child: Container(
                                alignment: Alignment.center,
                                height: 45.0,
                                decoration: BoxDecoration(
                                color: Color(0xFF1976D2),
                                borderRadius: BorderRadius.circular(9.0)),
                                child: Text('Login',
                                style: TextStyle(
                                fontSize: 20.0, color: Colors.white))),
                                ),
                                ),
                                ),





                                share|improve this answer













                                class Loader extends StatefulWidget {
                                @override
                                State createState() => LoaderState();
                                }

                                class LoaderState extends State<Loader> with SingleTickerProviderStateMixin {
                                AnimationController controller;
                                Animation<double> animation;

                                @override
                                void initState() {
                                super.initState();
                                controller = AnimationController(
                                duration: Duration(milliseconds: 1200), vsync: this);
                                animation = CurvedAnimation(parent: controller, curve: Curves.elasticOut);
                                animation.addListener(() {
                                this.setState(() {});
                                });
                                animation.addStatusListener((AnimationStatus status) {});
                                controller.repeat();
                                }

                                @override
                                void dispose() {
                                controller.dispose();
                                super.dispose();
                                }

                                @override
                                Widget build(BuildContext context) {
                                return Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 100.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue[300],
                                height: 3.0,
                                width: animation.value * 75.0,
                                ),
                                Padding(
                                padding: EdgeInsets.only(bottom: 5.0),
                                ),
                                Container(
                                color: Colors.blue,
                                height: 3.0,
                                width: animation.value * 50.0,
                                )
                                ],
                                );
                                }
                                }


                                Expanded(
                                child: Padding(
                                padding:
                                EdgeInsets.only(left: 20.0, right: 5.0, top:20.0),
                                child: GestureDetector(
                                onTap: () {
                                Navigator.push(
                                context,
                                MaterialPageRoute(
                                builder: (context) => FirstScreen()));
                                },
                                child: Container(
                                alignment: Alignment.center,
                                height: 45.0,
                                decoration: BoxDecoration(
                                color: Color(0xFF1976D2),
                                borderRadius: BorderRadius.circular(9.0)),
                                child: Text('Login',
                                style: TextStyle(
                                fontSize: 20.0, color: Colors.white))),
                                ),
                                ),
                                ),






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Dec 24 '18 at 21:01









                                Max ZubkoMax Zubko

                                114




                                114













                                • How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

                                  – Max Zubko
                                  Dec 24 '18 at 21:01



















                                • How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

                                  – Max Zubko
                                  Dec 24 '18 at 21:01

















                                How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

                                – Max Zubko
                                Dec 24 '18 at 21:01





                                How can I combine a class that creates a loading indicator with my button, so that when I press it, the indicator turns on and flips to the next page ?

                                – Max Zubko
                                Dec 24 '18 at 21:01


















                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47065098%2fhow-work-with-progress-indicator-in-flutter%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                                Calculate evaluation metrics using cross_val_predict sklearn

                                Insert data from modal to MySQL (multiple modal on website)