Flutter 避免StreamBuilder刷新颤振中的运行设置状态
我有一个显示2个元素的页面,它们都是不同的Flutter 避免StreamBuilder刷新颤振中的运行设置状态,flutter,Flutter,我有一个显示2个元素的页面,它们都是不同的StreamBuilder,但第二个元素取决于第一个元素。 为了更清楚,我显示以下内容: Firebase documents (list) Firebase user 如果我们注销这两个StreamBuilder将消失。这很好,但是当我需要从列表中选择一个文档时,我的问题就出现了: return ListTile( leading: FlutterLogo(size: 40.0), title: Text(set["title"]), selecte
StreamBuilder
,但第二个元素取决于第一个元素。
为了更清楚,我显示以下内容:
Firebase documents (list)
Firebase user
如果我们注销这两个StreamBuilder
将消失。这很好,但是当我需要从列表中选择一个文档时,我的问题就出现了:
return ListTile(
leading: FlutterLogo(size: 40.0),
title: Text(set["title"]),
selected: _selected[index],
trailing: Badge(
badgeColor: Colors.grey,
shape: BadgeShape.circle,
toAnimate: true,
onTap: () => setState(() => _selected[index] = !_selected[index]),
);
每次执行SetState()
时,我都会刷新第一个StreamBuilder
(不知道为什么),并用它刷新第二个
这是列表小部件:
Widget _mySetsLists(BuildContext context) {
List<bool> _selected = List.generate(20, (i) => false);
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (context, snapshot) {
FirebaseUser user = snapshot.data;
if (snapshot.hasData) {
return StreamBuilder(
stream: Firestore.instance
.collection('users')
.document(user.uid)
.collection('sets')
.snapshots(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return new ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot set = snapshot.data.documents[index];
return ListTile(
leading: FlutterLogo(size: 40.0),
title: Text(set["title"]),
selected: _selected[index],
onTap: () => setState(() => _selected[index] = !_selected[index]),
);
},
);
} else {
return Center(
child: new CircularProgressIndicator(),
);
}
},
);
} else {
return Text("loadin");
}
},
);
}
}
Widget\u mySetsLists(构建上下文){
列表_selected=List.generate(20,(i)=>false);
返回流生成器(
流:FirebaseAuth.instance.onAuthStateChanged,
生成器:(上下文,快照){
FirebaseUser=snapshot.data;
if(snapshot.hasData){
返回流生成器(
流:Firestore.instance
.collection('用户')
.document(user.uid)
.collection('集合')
.snapshots(),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
返回新的ListView.builder(
收缩膜:对,
itemCount:snapshot.data.documents.length,
itemBuilder:(上下文,索引){
DocumentSnapshot set=snapshot.data.documents[index];
返回列表块(
领先:标志(尺寸:40.0),
标题:文本(集合[“标题]),
已选择:_已选择[索引],
onTap:()=>设置状态(()=>(您选择的[索引]=!(您选择的[索引]),
);
},
);
}否则{
返回中心(
子项:新的CircularProgressIndicator(),
);
}
},
);
}否则{
返回文本(“加载”);
}
},
);
}
}
这是用户配置文件:
class UserProfileState extends State<UserProfile> {
@override
Widget build(BuildContext context) {
return SliverList(
delegate: SliverChildListDelegate(
[
_mySetsLists(context),
Divider(),
StreamBuilder<FirebaseUser>(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
FirebaseUser user = snapshot.data;
if (user == null) {
return Text('not logged in');
}
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
user.photoUrl,
),
),
title: Text(user.displayName),
subtitle: Text(user.email),
trailing: new IconButton(
icon: new Icon(Icons.exit_to_app),
highlightColor: Colors.pink,
onPressed: () {
authService.signOut();
}),
);
} else {
return Text("loading profile"); // <---- THIS IS WHAT I SEE
}
},
),
],
),
);
}
class UserProfileState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回银表(
委托:SliverChildListDelegate(
[
_mySetsLists(上下文),
分隔符(),
StreamBuilder(
流:FirebaseAuth.instance.onAuthStateChanged,
生成器:(上下文,快照){
if(snapshot.connectionState==connectionState.active){
FirebaseUser=snapshot.data;
if(user==null){
返回文本(“未登录”);
}
返回列表块(
领先:CircleAvatar(
背景图片:NetworkImage(
user.photoUrl,
),
),
标题:文本(user.displayName),
字幕:文本(user.email),
拖尾:新图标按钮(
图标:新图标(图标。退出到应用程序),
highlightColor:Colors.pink,
已按下:(){
authService.signOut();
}),
);
}否则{
返回文本(“加载配置文件”);//我也经历了同样的困难,但这是我使用的技巧
var itemsData = List<dynamic>();
var _documents = List<DocumentSnapshot>();
@override
void initState() {
// TODO: implement initState
super.initState();
getData();
}
getData(){
Firestore.instance
.collection('users')
.document(currentUser.uid)
.collection('set')
.getDocuments()
.then((value) {
value.documents.forEach((result) {
setState(() {
_documents.add(result);
itemsData.add(result.data);
});
});
});
}
希望能有帮助!!不确定你到底在问什么-你能详细说明并提供StreamBuilder
s的代码片段吗?问题是当我在第二个StreamBuilder
上更新SetState()
时。如注释所示,它会刷新第一个(显示正在加载…
)使我的值选择值消失。我希望我可以详细说明一下,但我不确定这里的问题是什么。代码基本上是我看不到StreamBuilder
s,因此很难尝试查看出了什么问题。可能有很多问题,例如StreamBuilder
都在StatefulWidget
中您正在重建或其他任何操作。您显示的ListTile中有一个按钮可以更改状态,但您的其余代码是一个完整的黑框,因此我无法真正向您指出任何方向:/I更新问题。希望它看起来不太多。我意识到了一些事情。在列表中,我在正在运行的小部件上有快照.hasData
显示加载文本时,我拥有的是snapshot.connectionState==connectionState.active
。同时显示第一个文本时,我没有看到显示任何消息的任何问题,但选择仍然不起作用(基本上是因为每次单击其中一个元素时列表都会呈现)即使我从该页面移动到下一个页面,StreamBuilder
也会再次触发(并且两次)
ListView.builder(
shrinkWrap: true,
itemCount: _documents.length,
itemBuilder: (context, index) {
return ListTile(
title:Text(itemsData[index]['name'])
)
})