过滤 Streambuilder/listviewBuilder 颤动

Posted

技术标签:

【中文标题】过滤 Streambuilder/listviewBuilder 颤动【英文标题】:filtering Streambuilder/ listviewBuilder flutter 【发布时间】:2020-10-18 18:32:41 【问题描述】:

我是 Flutter 的新手,我一直在尝试创建一个基于用户选择刷新 ListView.builder 的函数。我将城市名称作为字符串保存在我的用户集合中的 Firestore 文档中。 我有多个按钮来显示不同的城市,并且根据选择我需要 ListView 构建器来重建。我一直在努力寻找解决方案。 这里有人可以帮忙吗?

这就是我从 firestore 检索数据的方式

 StreamBuilder(
              stream: Firestore.instance.collection('users').snapshots(),
              builder: (context, snapshot) 
                if (!snapshot.hasData) return Text('loading...');

               return Container(
                  width: 890.0,
                  height: 320.0,
                  margin: EdgeInsets.symmetric(
                      vertical: 10.0, horizontal: 00.0),
                  child: new ListView.builder(
                      scrollDirection: Axis.horizontal,
                      itemCount: snapshot.data.documents.length,
                      itemBuilder: (BuildContext context, int index) 
                        User user = User.fromDoc(snapshot.data
                            .documents[index]);
                        return Padding(
                          padding: const EdgeInsets.only(top: 0),
                          child: Container(
                              height: 300,
                              width: 300,
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(0),
                              ),
                              child: _buildCard(user)),
                        );
                      ),
                );
              ,
            ),

【问题讨论】:

基于选择是什么意思? hi @Henok ,基于按下的按钮。我所有的用户都有一个名为 myCity 的字段。我想在我的 feedscreen 中创建代表不同城市的按钮。因此,根据按下的按钮,listview.builder 应该只返回该城市的用户。 有多种方法可以解决这个问题,解决方案1是针对城市的静态数量(如果有固定数量的城市)创建n个StreamBuilders,我们需要使用IndexedStack隐藏和显示小部件,解决方案2 是针对城市的动态数量,因此我们需要将查询放入变量中并更改其状态。 感谢@Henok。它们听起来都很有希望,但我不知道如何实现它们。您是否可以指导我查看样品或告诉我如何使用这种方式完成此操作?我正在使用城市的静态数字 【参考方案1】:

我刚刚编写了这段代码来显示静态城市编号的实现,单击按钮会更改索引,然后更改文本(您将它们更改为具有自定义城市流的流构建器),您还可以将其缩放为动态通过操作城市列表来列出。


class MyHomePage extends StatefulWidget 
  MyHomePage(Key key,) : super(key: key);
​
​
  @override
  _MyHomePageState createState() => _MyHomePageState();

​
class _MyHomePageState extends State<MyHomePage> 
  int stackIndex = 0;
​
  final List<String> cities = ['Berlin', 'Denver', 'Nairobi', 'Tokyo', 'Rio'];
  
​
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment : MainAxisAlignment.spaceEvenly,
        children : [
          Row(
            mainAxisAlignment : MainAxisAlignment.spaceEvenly,
            mainAxisSize : MainAxisSize.max,
          children : cities.map((city)
            return RaisedButton(
              child : Text(city),
              onPressed : ()
                setState(()
                  this.stackIndex = cities.indexOf(city);
                );
              
            );
          ).toList()
          ),
          
          IndexedStack(
          index : stackIndex,
          children: cities.map((city)
            return yourStreamBuilder(city);
          ).toList()
        ),
        ])
      ),
     
    );
  
  
  Widget yourStreamBuilder(String city)
    //you can use your custom stream here
    //Stream stream = Firestore.instance.collection('users').where('myCity', isEqualTo: city).snapshots();
​
​
    return Text(city);//replace this with your streamBuilder 
  

​


【讨论】:

感谢@Henok。我正在尝试设置它,但我在控制台中收到此错误。颤振:类型 'MappedListIterable' 不是类型 'List' 的子类型 你能告诉我它在哪一行抛出错误吗? 我不确定。对不起,我很新。我可以在这里发布我的代码以便您查看吗?再次感谢【参考方案2】:
 int stackIndex = 0;
 final List<String> cities =[
    'Stockholm',
    'Malmö',
    'Uppsala',
    'Västerås',
    'Örebro',
    'Linköping',
    'Helsingborg',
    'Jönköping',
    'Norrköping',
    'Lund',
    'Umeå',
    'Gävle',
    'Södertälje',
    'Borås',
    'Huddinge',
    'Eskilstuna',
    'Nacka',
    'Halmstad',
    'Sundsvall',
    'Södertälje',
    'Växjö',
    'Karlstad',
    'Haninge',
    'Kristianstad',
    'Kungsbacka',
    'Solna',
    'Järfälla',
    'Sollentuna',
    'Skellefteå',
    'Kalmar',
    'Varberg',
    'Östersund',
    'Trollhättan',
    'Uddevalla',
    'Nyköping',
    'Skövde',
  ];



  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment : MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Row(
              mainAxisAlignment : MainAxisAlignment.spaceEvenly,
              mainAxisSize : MainAxisSize.max,
              children: cities.map((city) 
                return OutlineButton(
                  child: Text(city),
                  onPressed: ()
                    setState(() 
                      this.stackIndex = cities.indexOf(city);
                    );
                    ,
                );
              ).toList()
            ),
            IndexedStack(
              index: stackIndex,
              children: cities.map((city)
                return myStreamBuilder(city);
              )
            )
          ],
        ),
      ),
    );
  

  Widget myStreamBuilder(String city)
    Stream stream = Firestore.instance.collection('users').where('myCity', isEqualTo: city).snapshots();
    return Text(city);
  

【讨论】:

cities.map 应该以 .toList() 结尾,这就是导致错误的原因 谢谢@Henok,我错过了。现在我收到一个新错误,说类型“List”不是“List”类型的子类型。非常感谢您抽出宝贵时间 任何时候很乐意帮助 Rizzo ,新错误是否显示该行? 谢谢@Henok,我收到了一些错误信息,但可能是第 97 行吗?抛出异常时,这是堆栈:#0 _FeedScreenState.build (package:luncha/screen/feed_screen.dart:97:18) @Henok 我通过在地图前添加 使其工作。现在,当我按下按钮时,它会导航到特定用户,但不会隐藏其余的?非常感谢

以上是关于过滤 Streambuilder/listviewBuilder 颤动的主要内容,如果未能解决你的问题,请参考以下文章

StreamBuilder ListView 在首次加载时从 Firestore 返回空列表

过滤器的原理是啥?

布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter

高效过滤器的检漏过程

wireshark怎么过滤端口

wireshark过滤规则