Flutter 中 ChangeNotifier 的构建器小部件
Posted
技术标签:
【中文标题】Flutter 中 ChangeNotifier 的构建器小部件【英文标题】:Builder widget for ChangeNotifier in Flutter 【发布时间】:2021-07-04 23:35:34 【问题描述】:背景
ValueNotifier
有一个 ValueListenableBuilder
小部件。
Stream
有一个 StreamBuilder
小部件。
Future
有一个 FutureBuilder
小部件。
问题
ChangeNotifier
的生成器是什么?
我尝试了什么
我尝试将ValueListenableBuilder
与ChangeNotifier
一起使用,但ChangeNotifier
没有实现ValueListenable
。
我知道我可以使用Provider
包中的ChangeNotifierProvider
,但我想知道是否有不需要第三方包的解决方案。
【问题讨论】:
AnimatedBuilder
(或者AnimatedWidget
,如果你想要一些扩展AnimatedWidget
的自定义类)
@pskink,很有趣!我不会从名字中猜到的。
有时,我感觉就像走过你走过的那一步。每当我尝试在您的“极简主义”架构上构建时,我都会看到您的解决方案突然出现。我的页面的 ViewModel/Controller/Manager 类是 ChangeNotifier
,其中包含多个简单/复杂的 ValueNotifiers
。 UI 通过整个 ViewModel notifyListeners()
或其微调属性 ValueNotifiers 得到相应的通知。我使用 ChangeNotifier
作为 ViewModel,因为 ValueNotifier
子类需要相等性检查 ==
来通知。这意味着覆盖所说的==
+hashCode
或使用Equatable
。
由于上述原因,我一直在寻找ChangeNotifier
builder。这个问题/答案非常适合这种特殊情况。
@om-ha,我喜欢ChangeNotifier
,因为它简单易用。不过,我从来不需要在我的值通知程序中覆盖 ==
和 hashCode
。
【参考方案1】:
这是一个补充答案,演示了使用 AnimatedBuilder
在从 ChangeNotifier
更改时重建 UI。
这只是标准的计数器应用程序。
counter_model.dart
import 'package:flutter/foundation.dart';
class CounterModel extends ChangeNotifier
int _counter = 0;
int get count => _counter;
void increment()
_counter++;
notifyListeners();
main.dart
import 'counter_model.dart';
import 'package:flutter/material.dart';
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
home: MyHomePage(),
);
class MyHomePage extends StatefulWidget
MyHomePage(Key key) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
final _counterModel = CounterModel();
@override
Widget build(BuildContext context)
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
AnimatedBuilder(
animation: _counterModel,
builder: (context, child)
return Text(
'$_counterModel.count',
style: Theme.of(context).textTheme.headline4,
);
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _counterModel.increment,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
【讨论】:
【参考方案2】:ChangeNotifier 是 Listenable Widget 的直接实现,对于 Listenable,您可以使用 AnimatedBuilder,它会从 Listenable 触发重建,而无需传回特定值 此外,您的类可以从 ChangeNotifier 扩展并为其添加新功能,您可以基于这些新功能创建自定义 Builder 小部件
【讨论】:
【参考方案3】:您可以使用消费者来更改和构建您的 UI! 试试这些 - https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple
【讨论】:
Consumer
小部件是提供程序包的一部分,我一直在寻找非第三方解决方案。但是,阅读您的链接很有帮助,因为自从我上次阅读以来它已经更新。【参考方案4】:
您可以自己编写一个简单的小部件。
使用setState
作为ChangeNotifier
的侦听器。
class ChangeNotifierBuilder<T extends ChangeNotifier> extends StatefulWidget
const ChangeNotifierBuilder(
Key? key,
required this.value,
required this.builder,
) : super(key: key);
final T value;
final Widget Function(BuildContext context, T value) builder;
@override
_ChangeNotifierBuilderState<T> createState() =>
_ChangeNotifierBuilderState<T>();
class _ChangeNotifierBuilderState<T extends ChangeNotifier>
extends State<ChangeNotifierBuilder<T>>
@override
void initState()
widget.value.addListener(_listener);
super.initState();
@override
void didUpdateWidget(covariant ChangeNotifierBuilder<T> oldWidget)
if (widget.value != oldWidget.value)
_miggrate(widget.value, oldWidget.value, _listener);
super.didUpdateWidget(oldWidget);
@override
void dispose()
widget.value.removeListener(_listener);
super.dispose();
void _miggrate(Listenable a, Listenable b, void Function() listener)
a.removeListener(listener);
b.addListener(listener);
void _listener()
setState(() );
@override
Widget build(BuildContext context)
return widget.builder(context, widget.value);
【讨论】:
【参考方案5】:ChangeNotifierProvider
、ChangeNotifierProvider.value
和其他提供程序的构建器是 Consumer
:
ChangeNotifierProvider(
create: (context) => CounterModel(),
child: Consumer<CounterModel>(
builder: (context, model, child)
return Text('$model.count');
),
),
【讨论】:
以上是关于Flutter 中 ChangeNotifier 的构建器小部件的主要内容,如果未能解决你的问题,请参考以下文章
Flutter Listen 的 ChangeNotifier 类,它是 ChangeNotifier 的一个属性
如何在 Flutter 中使用 Provider 显示来自 ChangeNotifier 的错误