web-dev-qa-db-fra.com

Afficher le dialogue de progression circulaire dans Flutter

J'ai un formulaire de connexion avec deux champs de texte 'Nom d'utilisateur', 'Mot de passe' & un bouton 'Connexion'. Sur le robinet du bouton de connexion, j'appelle une API. Je veux montrer une CircularProgressIndicator lors de cet appel d'api. La boîte de dialogue de progression doit apparaître dans le centre et en haut du formulaire de connexion. J'ai essayé FutureBuilder mais il masque le formulaire de connexion qui affiche CircularProgressIndicator uniquement. Je veux que tout le contenu de l'écran soit affiché derrière la CircularProgressIndicator.

Code complet:

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();
    }
  }

}
2
Poras Bhardwaj

Cette démo (avec le code source) devrait être très proche de ce que vous essayez de faire.

 enter image description here

Cela inclut le déclenchement des validateurs de formulaire avant et après l'appel asynchrone. 

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

4
mmccabe

Vous pouvez essayer l'extrait de code ci-dessous pour cela

class ProgressHUD extends StatelessWidget {

  final Widget child;
  final bool inAsyncCall;
  final double opacity;
  final Color color;
  final Animation<Color> valueColor;

  ProgressHUD({
    Key key,
    @required this.child,
    @required this.inAsyncCall,
    this.opacity = 0.3,
    this.color = Colors.grey,
    this.valueColor,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    List<Widget> widgetList = new List<Widget>();
    widgetList.add(child);
    if (inAsyncCall) {
      final modal = new Stack(
        children: [
          new Opacity(
            opacity: opacity,
            child: ModalBarrier(dismissible: false, color: color),
          ),
          new Center(
            child: new CircularProgressIndicator(
              valueColor: valueColor,
            ),
          ),
        ],
      );
      widgetList.add(modal);
    }
    return Stack(
      children: widgetList,
    );
  }
}

Utilise le

 body: ProgressHUD(
          child: screen,
          inAsyncCall: _isLoading,
          opacity: 0.0,
        ),

changez simplement l’état de _isloading true si vous souhaitez afficher la progression.

0
Sunil