Flutter Provider:如何监听类字段内部的类字段变化?
Posted
技术标签:
【中文标题】Flutter Provider:如何监听类字段内部的类字段变化?【英文标题】:Flutter Provider: How do I listen to a change of a class field inside a class field? 【发布时间】:2020-08-13 23:51:35 【问题描述】:给定以下 Dart/Flutter 类结构:
import 'package:flutter/material.dart';
class A with ChangeNotifier
B _element1;
B _element2;
B get element1 => _element1;
B get element2 => _element2;
set element1(B value)
_element1 = value;
notifyListeners();
set element2(B value)
_element2 = value;
notifyListeners();
class B
String x;
String y;
我正在尝试收听A.element1.x
的变化,但问题是,B 类的setter 无法调用A 类的notifyListeners()
,所以要么我在听A 并且不会注意到改变,或者我正在听 B,而我正在将上下文丢失给 A。
我在我的 Flutter 项目中使用 Provider 包。但我不确定,如果我误解了 Provider 包或 ChangeListeners 的概念。无论哪种方式,我都无法找到一个优雅的解决方案。
是否有可能从 A 类覆盖 B 类的 setter? 我显然可以为每个 element1 和 element2 字段(x,y)实现一个函数。但我猜这不是好的代码风格。
【问题讨论】:
有多种(一如既往;))方法可以解决这个问题:您可以在 B 类中注册一个回调,然后调用 A 类的函数,以便 A 类知道何时通知侦听器因为 B 的变化。或者使用流,由 B 公开并由 A 收听。但也许最好是查看 ProxyProvider 包。我没有这方面的经验,但我认为它可能适合您的用例。这是一个article。 你能帮我解决一下回调函数吗?我不熟悉回调函数。我查看了这篇文章,但找不到针对我的特定问题的解决方案。我还查看了文档,但不知道如何使用 ProxyProvider 来解决我的问题。 在下面发布了一个示例。这就是回调在 A 中调用notifyListeners
的方式。我不确定这是否比仅在 A 上调用方法更好,然后在 B 上设置属性并直接调用 notifyListeners
。
【参考方案1】:
这是一个关于如何使用回调函数的示例。如果没有回调,A 将不会调用 notifyListeners
并且您的 Home
小部件不会重建。这是一个关于VoidCallback
是什么的简短视频:https://www.youtube.com/watch?v=fWlPwj1Pp7U
主函数和一个简单的Home
视图:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'a.dart';
void main()
runApp(
ChangeNotifierProvider<A>(
create: (context) => A(),
child: MaterialApp(
home: Home(),
),
)
);
class Home extends StatelessWidget
@override
Widget build(BuildContext context)
return Consumer<A>(
builder: (context, model, child)
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('$model.element1.x'),
RaisedButton(
child: Text("Set x of element1."),
onPressed: ()
Provider.of<A>(context, listen: false).element1.setX = 'Set to new value';
,
),
],
),
),
)
);
,
);
然后是A类:
import 'package:flutter/material.dart';
import 'package:tryout/b.dart';
class A extends ChangeNotifier
B _element1 = B();
B _element2 = B();
B get element1 => _element1;
B get element2 => _element2;
A()
_element1.callback = () => notifyListeners();
_element2.callback = () => notifyListeners();
set element1(B value)
_element1 = value;
_element1.callback = () => notifyListeners();
notifyListeners();
set element2(B value)
_element2 = value;
_element2.callback = () => notifyListeners();
notifyListeners();
B 类:
import 'package:flutter/cupertino.dart';
class B
String x = "";
String y = "";
VoidCallback callback;
B(
this.callback
);
set setX(String newValueX)
x = newValueX;
if(callback != null) callback();
void setY(String newValueY)
y = newValueY;
if(callback != null) callback();
【讨论】:
以上是关于Flutter Provider:如何监听类字段内部的类字段变化?的主要内容,如果未能解决你的问题,请参考以下文章
在 Flutter 中,是不是可以使用 Provider 创建监听函数