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

Firebase 如何在SliverGrid中添加过滤器以仅显示StreamBuilder结果的一部分,firebase,flutter,google-cloud-firestore,Firebase,Flutter,Google Cloud Firestore,我有一个SliverGrid,它使用来自Firestore的StreamBuilder的结果填充 现在我有其他屏幕,可以按类别过滤结果,但这意味着每次用户选择类别时都会请求Firebase,因为我在查询中进行过滤 因此,我在想,是否有任何方法可以在应用程序中“本地”过滤结果,而不是再次调用服务器,因为所有信息都已加载 我的问题是,是否有办法在“SliverGrid”中添加一个过滤器,只显示符合条件的结果 这是我的代码中关于流和SliverGrid的部分: return Scaffold(

我有一个SliverGrid,它使用来自Firestore的StreamBuilder的结果填充

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

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

我的问题是,是否有办法在“SliverGrid”中添加一个过滤器,只显示符合条件的结果

这是我的代码中关于流和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,
                    ),
                ),
            ],
        );
    }),
);

好的,解决办法比我想象的简单

我添加了一个DropdownButton,在更改后更新状态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,
                        ),
                    ),
                ],
            );
        }),
    );
}
String-dropdownValue='all';
@凌驾
小部件构建(构建上下文){
变量菜单项={
“1”:“选项1”,
“2”:“选项2”,
“3”:“选项3”
};
var-firestoreQuery;
如果(dropdownValue=='all'){
firestoreQuery=(
Firestore.instance.collection('集合')
.orderBy('updated_at',descending:true)
.where('status',isEqualTo:'published')
.快照()
);
}否则{
firestoreQuery=(
Firestore.instance.collection('集合')
.orderBy('updated_at',descending:true)
.where('fielt_to_filter',isEqualTo:dropdownValue)
.where('status',isEqualTo:'published')
.快照()
);
}
返回脚手架(
正文:StreamBuilder(
流:firestoreQuery,
生成器:(BuildContext上下文,异步快照){
如果(!snapshot.hasData){
返回中心(
子对象:循环进程指示器()
);
}
返回自定义滚动视图(
条子:[
滑动双轴适配器(
儿童:[
纵队(
mainAxisAlignment:mainAxisAlignment.center,
mainAxisSize:mainAxisSize.max,
儿童:[下拉按钮(
value:dropdownValue,
项目:menuItems.entries
.地图(
(地图条目e)=>下拉菜单项(
值:e.key,
子项:文本(即值),
))
.toList(),
onChanged:(字符串newValue){
设置状态(){
dropdownValue=newValue;
});
},
),
]
),
),
银栅(
gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(
交叉轴计数:2,
儿童方面:1.3,
),
代表:SliverChildBuilderDelegate(
(上下文、索引){
回墨槽(
child:CustomWidget();
);
},
childCount:snapshot.data.documents.length,
),
),
],
);
}),
);
}

加载数据时,您可以将其保存到SQL lite