簡體   English   中英

在登錄頁面上添加循環進度指示器

[英]Adding Circular Progress Indicator on Login Page

我試圖在用戶登錄時在登錄頁面上添加一個循環進度指示器。我在我的模型類中聲明了 isLoading,並在 login() 函數中設置它。

class LoginPageModel extends ChangeNotifier {
  bool isLoading = false;

  login(String datasource, String username, String password,
      BuildContext context) async {
    isLoading = true;
    try {
      final result = await Client.auth(
        dataSource: datasource,
        username: username,
        password: password,
      );
      if (result) {
        Navigator.of(context).pushReplacement(
            MaterialPageRoute(builder: (context) => CustomersPage()));
      }
    } on ClientException catch (e) {
      debugPrint(e.prettyMessage());
    } catch (e) {
      debugPrint(e.toString());
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}

在 UI 方面,我將 CircularProgressIndicator 設置為根據 isLoading 的值進行顯示。

Widget build(BuildContext context) {
return ChangeNotifierProvider(
    create: (_) => LoginPageModel(),
    child: Consumer<LoginPageModel>(
      builder: (context, model, _) {
        return Scaffold(
          body: Center(
            child: Form(
              key: _formKey,
              child: Padding(
                padding: const EdgeInsets.all(60.0),
                child: Card(
                  shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(15)),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: Text(
                          'Log in',
                          style: Styles.titleTextStyle(),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: TextFormField(
                          decoration: Styles.textFormFieldDecoration(
                            labelText: 'Data Source',
                          ),
                          controller: _dataSourceController,
                          validator: (value) =>
                              value.isNotEmpty ? null : 'Required Field',
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: TextFormField(
                          decoration: Styles.textFormFieldDecoration(
                            labelText: 'Username',
                          ),
                          controller: _usernameController,
                          validator: (value) =>
                              value.isNotEmpty ? null : 'Required Field',
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: TextFormField(
                          obscureText: true,
                          decoration: Styles.textFormFieldDecoration(
                            labelText: 'Password',
                          ),
                          controller: _passwordController,
                          validator: (value) =>
                              value.isNotEmpty ? null : 'Required Field',
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: FlatButton(
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(15),
                              side: BorderSide(
                                  style: BorderStyle.solid,
                                  color: Colors.grey)),
                          child: Text(model.isLoading
                              ? 'Logging In . . '
                              : 'Submit'),
                          onPressed: () async {
                            if (_formKey.currentState.validate()) {
                              model.login(
                                _dataSourceController.text,
                                _usernameController.text,
                                _passwordController.text,
                                context,
                              );
                            }
                          },
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(15.0),
                        child: model.isLoading
                            ? CircularProgressIndicator()
                            : Container(),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      },
    ));
}

當我測試它時,圓形進度指示器沒有出現。 我需要在其他地方設置 isLoading 嗎? 是否正在跟蹤 isLoading 的狀態? 我想將 UI 和邏輯代碼分開並保持我的小部件無狀態。 這可能嗎?

不要在Model中使用isLoading,在UI文件中獲取model類的實例

final loginModel = LoginPageModel();
bool isLoading = false;

創建一個新函數

void login(parameters) async {
setState(() {
      isLoading = true;
    });

   await loginModel.login(parameters);

setState(() {
      isLoading = false;
    });
}

在小部件部分

...
return isLoading ? CircularProgressIndicator() 
       : Your Widget()
...

在 LoginPageModel 中,按照

isLoading = true;

notifyListeners();

您可以在下面復制粘貼運行完整代碼
第 1 步:您忘記添加notifyListeners

isLoading = true;
notifyListeners();

第 2 步:您需要SingleChildScrollView以避免鍵盤問題

 child: SingleChildScrollView(
          child: Form(
            key: _formKey,
            child: Padding(

工作演示

在此處輸入圖片說明

完整代碼

import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:provider/provider.dart';

class LoginPageModel extends ChangeNotifier {
  bool isLoading = false;

  login(String datasource, String username, String password,
      BuildContext context) async {
    isLoading = true;
    notifyListeners();
    try {
      await Future.delayed(Duration(seconds: 3), () {});
      /*
      final result = await Client.auth(
        dataSource: datasource,
        username: username,
        password: password,
      );
      if (result) {
        Navigator.of(context).pushReplacement(
            MaterialPageRoute(builder: (context) => CustomersPage()));
      }*/
    } on ClientException catch (e) {
      debugPrint(e.toString());
    } catch (e) {
      debugPrint(e.toString());
    } finally {
      isLoading = false;
      notifyListeners();
    }
  }
}

class Test extends StatelessWidget {
  final _formKey = GlobalKey<FormState>();
  final _dataSourceController = TextEditingController();
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
        create: (_) => LoginPageModel(),
        child: Consumer<LoginPageModel>(
          builder: (context, model, _) {
            return Scaffold(
              body: Center(
                child: SingleChildScrollView(
                  child: Form(
                    key: _formKey,
                    child: Padding(
                      padding: const EdgeInsets.all(60.0),
                      child: Card(
                        shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(15)),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: Text(
                                'Log in',
                                //style: Styles.titleTextStyle(),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: TextFormField(
                                decoration: InputDecoration(
                                  labelText: 'Data Source',
                                ),
                                controller: _dataSourceController,
                                validator: (value) =>
                                    value.isNotEmpty ? null : 'Required Field',
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: TextFormField(
                                decoration: InputDecoration(
                                  labelText: 'Username',
                                ),
                                controller: _usernameController,
                                validator: (value) =>
                                    value.isNotEmpty ? null : 'Required Field',
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: TextFormField(
                                obscureText: true,
                                decoration: InputDecoration(
                                  labelText: 'Password',
                                ),
                                controller: _passwordController,
                                validator: (value) =>
                                    value.isNotEmpty ? null : 'Required Field',
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: FlatButton(
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(15),
                                    side: BorderSide(
                                        style: BorderStyle.solid,
                                        color: Colors.grey)),
                                child: Text(model.isLoading
                                    ? 'Logging In . . '
                                    : 'Submit'),
                                onPressed: () async {
                                  if (_formKey.currentState.validate()) {
                                    model.login(
                                      _dataSourceController.text,
                                      _usernameController.text,
                                      _passwordController.text,
                                      context,
                                    );
                                  }
                                },
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(15.0),
                              child: model.isLoading
                                  ? CircularProgressIndicator()
                                  : Container(),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            );
          },
        ));
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Test(),
    );
  }
}

在 LoginPageModel 模型中確保你的 isLoading 應該是 true 並通知你的聽眾

isLoading = true; notifyListeners();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM