[英]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.