I have a login form with two textfields 'UserName', 'Password' & a button 'Login'. On tap of login button I am calling an API. I want to show a CircularProgressIndicator
during this api call. Progress dialog should show in the centre & top of login form.
I have tried FutureBuilder
but it hides the login form shows CircularProgressIndicator
only. I want all content of screen to show behind the CircularProgressIndicator
.
Full Code:
import 'package:flutter/material.dart';
import 'package:the_don_flutter/userModel.dart';
import 'package:validate/validate.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'signup.dart';
class Login extends StatefulWidget{
@override
State<Login> createState() {
// TODO: implement createState
return LoginFormState();
}
}
class LoginFormState extends State<Login>{
final GlobalKey<FormState> formKey = new GlobalKey<FormState>();
String _passwordValidation(String value){
if(value.isEmpty){
return "Field Can't be empty.";
}else if(value.length < 6)
return "Password must be of six characters long.";
return null;
}
String _checkValidEmail(String value){
try{
Validate.isEmail(value);
}catch(e){
return "Email is not valid.";
}
return null;
}
Future<User> _loginUser() async{
var response = await http.post("https://example/public/api/login", headers: {}, body: {'username':'[email protected]', 'password':'123456'})
.catchError((error) => print("Error $error"));
print("response of login ${response.body}");
return User.fromJson(json.decode(response.body));
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Container(
padding: EdgeInsets.only(left: 20.0, top: 100.0, right: 20.0),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bg_green.jpg"),
fit: BoxFit.fill)),
child: Column(
children: <Widget>[
Form(
key: formKey,
child: Column(children: <Widget>[
Padding(padding: EdgeInsets.only(bottom: 20.0),
child: TextFormField(
validator: _checkValidEmail,
decoration: InputDecoration(
hintText: "[email protected]",
labelText: "User Name",
hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
autofocus: true,),),
TextFormField(
obscureText: true,
validator: _passwordValidation,
decoration: InputDecoration(
hintText: "password",
labelText: "Password",
hintStyle: TextStyle(color: Colors.white)),
style: TextStyle(color: Colors.white),
autofocus: true,)
],),),
Padding(padding: EdgeInsets.only(top: 20.0),
child: Row(mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text("Forgot Password?", textAlign: TextAlign.start, style: TextStyle(color: Colors.white,),),
],),),
Padding(padding: EdgeInsets.only(top: 20.0),
child: GestureDetector(
onTap: _submitForm,
child: Row(mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text("LOGIN", textAlign: TextAlign.start, style: TextStyle(color: Colors.white, fontSize: 40.0),),
Icon(Icons.chevron_right, size: 40.0, color: Colors.white,),
],),), ),
Expanded(
child: Padding(padding: EdgeInsets.only(bottom: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text("Don't have an account?", textAlign: TextAlign.start, style: TextStyle(color: Colors.white,),),
Container(
margin: EdgeInsets.only(left: 8.0),
child: GestureDetector(
onTap: (){Navigator.push(context, MaterialPageRoute(builder: (context) => Signup()));},
child: Text("REGISTER NOW!", textAlign: TextAlign.start, style: TextStyle(color: Colors.black,),),
)),
],
),))
],
),
),
);
}
_submitForm() {
if(formKey.currentState.validate()){
print("Go to Home page");
_loginUser();
}
}
}
This demo (with source code) should be very close to what your trying to do
It includes triggering the form validators before and after the async call.