问题描述
嗯,这个问题有点简单,但需要以特定的方式完成。首先,我有一个扩展“ChangeNotifier”的类,该类将执行一些异步任务,因此在执行此操作时,有一个变量指示该类当前是否忙碌,到目前为止它可以完美运行。
使用 Riverpod 作为状态管理我实例化了所述类并沿着我的小部件树提供它,但是有一个小部件需要显示一个对话框,并且在这个对话框中它可以从我一直传递的类中执行异步任务。除了我想在这个对话框中显示一个 CircularProgressIndicator 之外,一切都有效,而且它似乎没有对状态变化做出正确的反应。
这是重新创建场景的示例代码:
import 'package:Flutter/material.dart';
import 'package:Flutter_hooks/Flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
final dataProvider = ChangeNotifierProvider<Data>((_) => Data());
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'huh?',theme: ThemeData(primarySwatch: Colors.blue),home: FirstPage(),);
}
}
class FirstPage extends HookWidget {
@override
Widget build(BuildContext context) {
final data = useProvider(dataProvider);
print('DATA STATE [source: FirstPage,data: ${data.loading}]');
return Scaffold(
body: Center(
child: Container(
width: 200,height: 50,child: ElevatedButton(
child: Text('show dialog'),onpressed: () => showDialog(
context: context,builder: (_) => Alert(data: data),),);
}
}
class Alert extends StatelessWidget {
const Alert({required this.data});
final Data data;
Widget build(BuildContext context) {
print('DATA STATE [source: Alert,data: ${data.loading}]');
return AlertDialog(
content: Container(
width: 500,height: 500,padding: EdgeInsets.symmetric(horizontal: 100,vertical: 200),child: ElevatedButton(
child: data.loading ? CircularProgressIndicator(color: Colors.white) : Text('click here'),onpressed: () async => await data.randomTask(),);
}
}
class Data extends ChangeNotifier {
Data({
this.loading = false,});
bool loading;
Future<void> randomTask() async {
print('Actually waiting 3 seconds..');
_update(loading: true);
await Future.delayed(Duration(seconds: 3));
print('Waiting done.');
_update(loading: false);
}
void _update({bool? loading}) {
this.loading = loading ?? this.loading;
notifyListeners();
}
}
请注意我放置的打印件,因为如果您运行应用程序,您将在控制台上看到如下输出:
DATA STATE [source: FirstPage,data: false]
DATA STATE [source: Alert,data: false]
Actually waiting 3 seconds..
DATA STATE [source: FirstPage,data: true]
Waiting done.
DATA STATE [source: FirstPage,data: false]
这意味着状态实际上正在发生变化,并且一切正常,除了似乎是静态的对话框。
我已经尝试添加一个“加载”布尔值作为“警报”小部件的一部分,并让它管理自己的状态,并且它可以工作,但是代码并不像我想要的那样干净,因为类“数据”应该管理这种东西。
有什么可以做的吗?
提前致谢!
解决方法
添加 StatefulBulider 即可
class Alert extends StatelessWidget {
const Alert({required this.data});
final Data data;
Widget build(BuildContext context) {
print('DATA STATE [source: Alert,data: ${data.loading}]');
return AlertDialog(
content: StatefulBuilder(builder: (context,setState) {
return Container(
width: 500,height: 500,padding: EdgeInsets.symmetric(horizontal: 100,vertical: 200),child: ElevatedButton(
child: data.loading
? CircularProgressIndicator(color: Colors.white)
: Text('click here'),onPressed: () async => await data.randomTask(),),);
}),);
}
}