flutter - 我可以将 setState 仅用于一个小部件而不是整个页面吗?
问题描述
我有一个 Future,它从我的 Cloud Firestore 数据库中获取一个值,并在我的应用程序正文中显示一个图标。如果数据库中的值发生更改,则图标会更新。我一直在使用 setState 来重建我的小部件树,并且效果很好 - 该应用程序几乎可以立即对我的 Cloud Firestore 数据库中的更改做出反应。这很棒!代码:
Future<void> takenSurvey2() async {
final sn = await Firestore.instance
.collection('Controller')
.document('Current Survey')
.get();
surveyName2 = sn['cs'];
final snapShot = await Firestore.instance
.collection('$surveyName2' + '_entrants')
.document(userid)
.get();
if (snapShot.exists) {
takenSurvey = true;
} else {
takenSurvey = false;
}
setState(() {});
}
并且显示图标的位置编码如下(在堆栈内):
Positioned(
right: 30,
top: 20,
child: FutureBuilder(
future: takenSurvey2(),
builder: (context, snapshot) {
if (takenSurvey == false) {
return Icon(
Foundation.burst_new,
size: 48,
color: Color(0xff303841),
);
} else if (takenSurvey == true) {
return Icon(
Foundation.check,
size: 48,
color: Color(0xff303841),
);
} else
return Container();
})),
但是,我使用“admob_flutter”包在我的 AdMob 广告中添加了,因为 setState 似乎一直在运行,所以广告无法加载 - 我只看到一个闪烁的框。如果我从上面的代码中删除 setState,则广告会加载,但当 Cloud Firestore 中的值更改时,我的应用程序中的图标不会更新。
如何从 setState 中排除我的 admob_flutter 小部件,或者仅使用 setState(或其他东西)来仅更新我的 FutureBuilder 小部件?我想以限制 Cloud Firestore 上的调用次数的方式这样做,但这不是必需的。
我尝试过使用嵌套条件逻辑,但它似乎不起作用!
谢谢!
解决方案
我可以建议你使用ValueNotifier,如果你想操作简单的数据,比如在这种情况下是一个布尔值,这个小部件可以是完美的。您也可以使用 avoid function
而不是 a future
,如下所示:
// Add a ValueNotifier for a single value
final ValueNotifier<bool> _takenSurvey = ValueNotifier(null);
void takenSurvey2() async {
final sn = await Firestore.instance
.collection('Controller')
.document('Current Survey')
.get();
surveyName2 = sn['cs'];
final snapShot = await Firestore.instance
.collection('$surveyName2' + '_entrants')
.document(userid)
.get();
if (snapShot.exists) {
// Update the value of the ValueNotifier
_takenSurvey.value = true;
} else {
_takenSurvey.value = false;
}
}
并使用ValueListenableBuilder监听该值的变化:
Positioned(
right: 30,
top: 20,
child: ValueListenableBuilder(
valueListenable: _takenSurvey,
builder: (context, takenSurvey, child) {
if(takenSurvey == null){
return Container();
}
else{
if (takenSurvey == false) {
return Icon(
Foundation.burst_new,
size: 48,
color: Color(0xff303841),
);
} else {
return Icon(
Foundation.check,
size: 48,
color: Color(0xff303841),
);
}
}
},
),
)
希望能帮助到你。
推荐阅读
- python - 通过将字符串列转换为pyspark中的整数类型来获取非空值的计数 - sql
- javascript - 等效于 fs.readFile() -> 到 -> 在 DOM 中上传 HTML
- python - 更新矢量化函数内的 tqdm 进度条
- python - 删除长度大于 1 的数字
- python - python-uno 如何使用管道操作 libreoffice-calc?
- javascript - 为什么我不能使用 vanilla JavaScript 重新获取我网站的数据?
- java - session.getAttribute 为 Chrome 浏览器返回 null。(小服务程序)
- python - 有没有办法踢/禁止 discord.py 中的每个人?
- python - Python - 使用 OpenWeatherMap API 问题
- java - java socket连接到代理而不是实际的服务器