为什么Flutter对话框没有在更改通知程序上重建



这个问题有点简单,但需要以特定的方式完成。首先,我有一个类扩展";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]

这意味着状态实际上在改变,除了看起来是静态的对话框之外,一切都很好。

我已经尝试添加一个";加载";bool作为";警报";小部件,并让它管理自己的状态,它就可以工作了,但代码并不像我希望的那样干净,因为Class;数据";应该管理这种事情。

有什么可以做的吗?

提前谢谢!

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

最新更新