下面的最小可重现代码旨在在按下按钮时有一个加载图标(以模拟发生异步计算时的加载)。
出于某种原因,消费者提供者在回调期间不会重建小部件。
我的观点:
class HomeView extends StatefulWidget {
const HomeView();
@override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ChangeNotifierProvider(
create: (_) => HomeViewModel(99),
child: Consumer<HomeViewModel>(
builder: (_, myModel, __) => Center(
child: ButtonsAtBottom(
addEventAction: () => myModel.increment(context),
busy: myModel.busy
),
),
),
),
);
}
}
我模拟执行业务逻辑的模型:
class HomeViewModel extends LoadableModel {
late int integer;
HomeViewModel(this.integer);
void increment(BuildContext context) {
super.setBusy(true);
Future.delayed(Duration(seconds: 3), () => print(integer++));
super.setBusy(false);
//Passed in context just to try to simulate my real app
//print(context);
}
}
class LoadableModel extends ChangeNotifier {
bool _busy = false;
bool get busy => _busy;
void setBusy(bool value) {
_busy = value;
notifyListeners();
}
}
问题:当回调执行时,其中的 setBusy()
方法被执行,它们应该通知监听器并更新传入的 busy
字段。随后,应显示文本或加载程序。
但是,busy
字段永远不会更新并保持为 false
。
class ButtonsAtBottom extends StatelessWidget {
final bool busy;
final void Function() addEventAction;
const ButtonsAtBottom({required this.busy, required this.addEventAction});
@override
Widget build(BuildContext context) {
print("busy value: $busy");
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
onPressed: () => Navigator.pop(context),
icon: Icon(Icons.clear_rounded),
),
ElevatedButton.icon(
onPressed: addEventAction,
icon: Icon(Icons.save_alt_rounded),
label: busy
? CircularProgressIndicator.adaptive(
backgroundColor: Colors.white,
)
: Text("Save")),
],
);
}
}
答案 0 :(得分:0)
你尝试过等待未来吗? ?