Flutter 避免StreamBuilder刷新颤振中的运行设置状态

Flutter 避免StreamBuilder刷新颤振中的运行设置状态,flutter,Flutter,我有一个显示2个元素的页面,它们都是不同的StreamBuilder,但第二个元素取决于第一个元素。 为了更清楚,我显示以下内容: Firebase documents (list) Firebase user 如果我们注销这两个StreamBuilder将消失。这很好,但是当我需要从列表中选择一个文档时,我的问题就出现了: return ListTile( leading: FlutterLogo(size: 40.0), title: Text(set["title"]), selecte

我有一个显示2个元素的页面,它们都是不同的
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()
时。如注释所示,它会刷新第一个(显示
正在加载…
)使我的值选择值消失。我希望我可以详细说明一下,但我不确定这里的问题是什么。代码基本上是我看不到StreamBuilders,因此很难尝试查看出了什么问题。可能有很多问题,例如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'])
)


})