如何在SliverGrid中添加过滤器以仅显示部分StreamBuilder结果

时间:2019-08-18 21:23:52

标签: firebase flutter google-cloud-firestore

我有一个 SliverGrid ,其中填充了Firestore中 StreamBuilder 的结果。

现在,我还有其他屏幕可以按类别过滤结果,但这意味着每次用户选择类别时都会向Firebase发送请求,因为我是在查询中进行过滤的。

我想我是否有办法在应用程序中“本地”过滤结果,而不是再次调用服务器,因为所有信息都已加载。

我的问题是,是否可以在“ SliverGrid”中添加过滤器以仅显示符合条件的结果?

这是我的代码中带有Stream和 SliverGrid 的部分:

return Scaffold(
    body: StreamBuilder(
    stream: Firestore.instance.collection('COLLECTION')
            .orderBy('updated_at', descending: true)
            .where('status', isEqualTo : 'published')
            .snapshots(),

    builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (!snapshot.hasData) {
            return Center(
                child: CircularProgressIndicator()
            );
        }
        return CustomScrollView(
            slivers: [
                SliverGrid(
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 2,
                        childAspectRatio: 1.3,
                        ),
                    delegate: SliverChildBuilderDelegate(
                        (context, index) {

                            return InkWell(
                                child: CustomWidget();
                            );
                        },
                        childCount: snapshot.data.documents.length,
                    ),
                ),
            ],
        );
    }),
);

1 个答案:

答案 0 :(得分:0)

好的,解决方案比我想象的要容易。

我添加了一个 DropdownButton ,用于更新onChanged状态 dropdownValue

此外,我用一个根据 dropdownValue 值进行过滤的变量替换了中的查询。

这是带有过滤器的SliverGrid的代码:

String dropdownValue = 'all';

@override
Widget build(BuildContext context) {

    var menuItems = {
        '1': 'option 1',
        '2': 'option 2',
        '3': 'option 3'
    };

    var firestoreQuery;
    if (dropdownValue == 'all'){
        firestoreQuery = (
            Firestore.instance.collection('COLLECTION')
            .orderBy('updated_at', descending: true)
            .where('status', isEqualTo : 'published')
            .snapshots()
        );
    }else{
        firestoreQuery = (
            Firestore.instance.collection('COLLECTION')
            .orderBy('updated_at', descending: true)
            .where('fielt_to_filter', isEqualTo : dropdownValue)
            .where('status', isEqualTo : 'published')
            .snapshots()
        );
    }

    return Scaffold(
        body: StreamBuilder(
        stream: firestoreQuery,

        builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (!snapshot.hasData) {
                return Center(
                    child: CircularProgressIndicator()
                );
            }
            return CustomScrollView(
                slivers: [

                    SliverToBoxAdapter(
                        child:  <Widget>[
                            Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                mainAxisSize: MainAxisSize.max,
                                children: <Widget>[ DropdownButton(
                                    value: dropdownValue,
                                    items: menuItems.entries
                                        .map<DropdownMenuItem<String>>(
                                            (MapEntry<String, String> e) => DropdownMenuItem<String>(
                                                    value: e.key,
                                                    child: Text(e.value),
                                                ))
                                        .toList(),
                                    onChanged: (String newValue) {
                                        setState(() {
                                            dropdownValue = newValue;
                                        });
                                    },
                                ),
                                ]
                            ),
                    ),
                    SliverGrid(
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 2,
                            childAspectRatio: 1.3,
                            ),
                        delegate: SliverChildBuilderDelegate(
                            (context, index) {

                                return InkWell(
                                    child: CustomWidget();
                                );
                            },
                            childCount: snapshot.data.documents.length,
                        ),
                    ),
                ],
            );
        }),
    );
}