flutter - 当 Flutter 中的全局变量更改(异步)时更新小部件
问题描述
我对 Flutter 还很陌生,我发现自己陷入了我挖的坑。
我想要完成的事情很简单。我有一个全局变量。比方说var PlayerPointsToAdd
。然后我有这个有状态的小部件,它应该在每次这个全局变量不为零时更新自己。我希望能够addPointsToPlayer()
从另一个小部件调用。
到目前为止,我对有状态小部件的理解到此为止setState((){})
,我只能在有状态小部件本身内部调用。
下面的代码位于有状态小部件内的容器内。每当按下此按钮时,它都会根据返回的新列表调用 setState PlayerScoreBoard.add()
。
...
child: RaisedButton(
onPressed: () {
setState(() {
if (PointsToAddPlayer != 0) {
for (int i = 0; i < PointsToAddPlayer; i++) {
PlayerScoreBoard.add(new Icon(
Icons.check_circle_outline,
size: 11));
}
PointsToAddPlayer = 0;
}
我一直在阅读文档并在 YouTube 上观看 Flutter 视频,所以请不要忽略这个问题。我真的很难理解这一点。
我想我必须使用 Streams 来做到这一点。它们看起来有点复杂,但如果这是我使用它们的唯一方法。这是否意味着我应该创建一个全局变量,最好是一个包含变量的类,并将其变量流式传输到变量更新时需要更新的每个其他小部件。因此,此 ScoreBoard 小部件必须侦听来自全局类的 Stream 并自行更新。这是否允许我更改全局类中的变量并将相应的小部件自动更新为新状态?这是否意味着每个依赖于自身外部变量的小部件都必须监听流?我真的很感谢 ELI5 对 Stateful Widgets 和 Streams 之间的关系。
而且因为这个全局数据会一遍又一遍地更新很多次,所以使用 Future 是不可能的。
非常感谢。
我错误地说了一个全局类变量。我的意思是说像地图这样的东西,在那里我可以有类似的东西gameData.PlayerPoints
,或gameData.turn
。
解决方案
您可以尝试ValueListenableBuilder。
import 'package:flutter/material.dart';
final playerPointsToAdd =
ValueNotifier<int>(0); //TODO 1st: ValueNotifier declaration
void main() => runApp(TestApp());
class TestApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
routes: {
'/': (context) => HomePage(),
},
);
}
//TODO you can use StatelessWidget either
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) => Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
// TODO 3rd: change the value
onPressed: () => playerPointsToAdd.value++,
child: Text('Increase'),
),
ValueListenableBuilder(
//TODO 2nd: listen playerPointsToAdd
valueListenable: playerPointsToAdd,
builder: (context, value, widget) {
//TODO here you can setState or whatever you need
return Text(
//TODO e.g.: create condition with playerPointsToAdd's value
value == 0
? 'playerPointsToAdd equals 0 right now'
: value.toString());
},
),
RaisedButton(
onPressed: () => playerPointsToAdd.value--,
child: Text('Decrease'),
),
],
),
),
);
}
推荐阅读
- android - ViewModelProviders 已经过时了,应该换什么?
- php - 如何在不使用 API 的情况下生成 Trx 钱包
- django - 为 Django 查询集组合过滤器
- javascript - 如何将数量增加一并跟踪单击的项目?
- python - Python Tkinter - 小部件出错 - TclError:预期整数但得到“新”
- c - 未知错误函数'scanf("%[^\n]%*c", &sent);'
- html - 如果添加相对定位的元素,如何阻止 flexbox 容器增长?
- r - 具有colmeans条件的R样本数据框
- python-3.x - Visual Studio Code 中的 Python 获取 winError[5] 来自 idescripts 的访问被拒绝
- c# - 获取 ListView 中选定项目的信息 - WPF/C#