在Flutter中的Firestore列表上方添加搜索表单

时间:2019-04-29 10:24:03

标签: flutter google-cloud-firestore

我正在尝试在Firestore的项目列表上方呈现搜索表单,并根据表单中的内容进行本地过滤。

我尝试将两个小部件都这样添加到正文中,但它仅显示搜索表单:

body: Column(
    children: <Widget>[Searchform(), ContentWidget()],
),

这是显示基本列表的当前代码:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class Items extends StatefulWidget {
  Items({Key key}) : super(key: key);

  @override
  _ItemsState createState() => _ItemsState();
}

class _ItemsState extends State<Items> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Search'),
      ),
      body: ContentWidget(),
    );
  }
}

class Searchform extends StatelessWidget {
  final TextEditingController _searchController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _searchController,
      decoration: InputDecoration(
        labelText: "Search",
        hintText: "Search",
        prefixIcon: Icon(Icons.search),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.all(
            Radius.circular(15.0),
          ),
        ),
      ),
    );
  }
}

class ContentWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: Firestore.instance.collection('content').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return new Text('Loading...');
          default:
            return new ListView(
              children:
                  snapshot.data.documents.map((DocumentSnapshot document) {
                return new ListTile(
                  title: new Text(document['term']),
                );
              }).toList(),
            );
        }
      },
    );
  }
}

我当时想做的是将项目保存在本地状态,并根据搜索框中的输入内容对其进行过滤。

3 个答案:

答案 0 :(得分:0)

我在listview代码中提供了简单的过滤器记录。

class FilterDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return FilterState();
}
}

class FilterState extends State<FilterDemo> {
List<String> items, duplicateList;
TextEditingController editingController = TextEditingController();

@override
 void initState() {
// TODO: implement initState
super.initState();
items = List<String>.generate(1000, (i) => "Item $i");

duplicateList = items;
}

void filterSearchResults(String query) {
List<String> dummySearchList = List<String>();
dummySearchList.addAll(duplicateList);
if (query.isNotEmpty) {
  List<String> dummyListData = List<String>();
  dummySearchList.forEach((item) {
    if (item.contains(query)) {
      dummyListData.add(item);
    }
  });
  setState(() {
    items.clear();
    items.addAll(dummyListData);
  });
  return;
} else {
  setState(() {
    items.clear();
    items.addAll(duplicateList);
  });
}
}

@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
  appBar: AppBar(
    title: Text("Filter Demo"),
  ),
  body: Column(
    children: <Widget>[
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: TextField(
          onChanged: (value) {
            filterSearchResults(value);
          },
          controller: editingController,
          decoration: InputDecoration(
              labelText: "Search",
              hintText: "Search",
              prefixIcon: Icon(Icons.search),
              border: OutlineInputBorder(
                  borderRadius: BorderRadius.all(Radius.circular(25.0)))),
        ),
      ),
      Expanded(
        child: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text('${items[index]}'),
            );
          },
        ),
      ),
    ],
  ),
);
}
}

答案 1 :(得分:0)

I have provide Code how the saving the items in local state and filter them based on what is typed in the search box.

     class UserList extends StatefulWidget {
          final FirebaseUser user;
          final String currentUserId;
          UserList({this.currentUserId, this.user});
          @override
          _UserListState createState() => _UserListState();
        }

        class _UserListState extends State<UserList> {
          TextEditingController _signUpConfirmPassword = new TextEditingController();
          String _myValue = '';

          UniqueKey _myKey = UniqueKey();
          @override
          Widget build(BuildContext context) {
            return CupertinoPageScaffold(
                navigationBar: CupertinoNavigationBar(
                  middle: Text("UserList"),
                ),
                child: ListView(
                  shrinkWrap: true,
                  children: <Widget>[
                    Padding(
                        padding: EdgeInsets.all(10.0),
                        child: CupertinoTextField(
                          keyboardType: TextInputType.text,
                          //inputFormatters: [LengthLimitingTextInputFormatter(60)],
                          placeholder: 'Search For..',
        //                  placeholderStyle: TextStyle(
        //                      fontWeight: FontWeight.w200
        //                  ),
                          prefix: Padding(
                            padding: EdgeInsets.only(left: 10.0),
                            child: Icon(
                              Icons.search,
                            ),
                          ),
                          onChanged: (val) {
                            if (val.isNotEmpty) {
                              _myValue = val;
                            }
                            setState(() {
                              _myKey = UniqueKey();
                            });
                          },
                          decoration: BoxDecoration(
                              border: Border.all(color: primaryColor),
                              borderRadius: BorderRadius.circular(20.0)),
                        )),
                    SizedBox(height: 10.0),
                    Container(
                        key: _myKey,
                        child: FetchUsers(
                          user: widget.user,
                          myValue: _myValue,
                        )),
                  ],
                ));
          }
        }

        class FetchUsers extends StatefulWidget {
          final String myValue;
          final FirebaseUser user;
          FetchUsers({this.myValue, this.user});
          @override
          _FetchUsersState createState() => _FetchUsersState();
        }

        class _FetchUsersState extends State<FetchUsers> {
          List searchName = List();
          List userName = List();
          Future listOfUsers() {
            if (widget.myValue.isEmpty) {
              return Firestore.instance
                  .collection('users')
                  .where('Role', isEqualTo: 'user')
                  .orderBy('Created', descending: true)
                  .limit(10)
                  .getDocuments()
                  .then((d) {
                userName.clear();
                d.documents.forEach((f) {
                  userName.add(f);
                });
                return userName;
              });
            } else {
              return Firestore.instance
                  .collection('users')
                  .where('Role', isEqualTo: 'user')
                  .limit(10)
                  .getDocuments()
                  .then((d) {
                searchName.clear();
                d.documents.forEach((f) {
                  if (f.data['Name']
                      .toString()
                      .toLowerCase()
                      .contains(widget.myValue.toLowerCase())) {
                    searchName.add(f);
                  }
                });

                return searchName;
              });
            }
          }

          @override
          Widget build(BuildContext context) {
            return FutureBuilder(
              future: listOfUsers(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(
                    child: CupertinoActivityIndicator(),
                  );
                } else {
                  return ListView.separated(
                    physics: ClampingScrollPhysics(),
                    separatorBuilder: (context, int) {
                      return Divider();
                    },
                    itemCount: snapshot.data.length,
                    shrinkWrap: true,
                    padding: EdgeInsets.all(10.0),
                    itemBuilder: (context, index) {
                      return Card(
                          elevation: 7.0,
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(10.0)),
                          child: IntrinsicHeight(
                            child: Padding(
                              padding: const EdgeInsets.all(10.0),
                              child: Row(
                                crossAxisAlignment: CrossAxisAlignment.stretch,
                                children: <Widget>[
                                  Column(
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: <Widget>[
                                      Text(
                                        '   ${snapshot.data[index]['Name']}',
                                        style: TextStyle(
                                            color: outlineColor,
                                            fontWeight: FontWeight.bold),
                                      ),
                                      SizedBox(
                                        height: 5.0,
                                      ),
                                      Text(
                                        '   ${snapshot.data[index]['Email']}',
                                      ),
                                    ],
                                  ),
                                  Spacer(),
                                  Column(
                                    crossAxisAlignment: CrossAxisAlignment.start,
                                    children: <Widget>[
                                      RaisedButton.icon(
                                          shape: RoundedRectangleBorder(
                                              borderRadius:
                                                  BorderRadius.circular(20.0)),
                                          color: primaryColor,
                                          onPressed: () {
                                            Navigator.push(
                                                context,
                                                CupertinoPageRoute(
                                                    builder: (context) => Chat(
                                                          user: widget.user,
                                                          name: snapshot.data[index]
                                                              ['Name'],
                                                          peerId: snapshot.data[index]
                                                              ['UID'],
                                                        )));
                                          },
                                          icon: Icon(
                                            Icons.chat,
                                            color: themeColor,
                                          ),
                                          label: Text(
                                            "Chat",
                                            style: TextStyle(color: themeColor),
                                          )),
                                      RaisedButton.icon(
                                          shape: RoundedRectangleBorder(
                                              borderRadius:
                                                  BorderRadius.circular(20.0)),
                                          color: primaryColor,
                                          onPressed: () {
                                            Navigator.push(
                                                context,
                                                CupertinoPageRoute(
                                                    builder: (context) =>
                                                        SendNotificationOption(
                                                          name: snapshot.data[index]
                                                              ['Name'],
                                                          myFcm: snapshot.data[index]
                                                              ['UID'],
                                                          isBroadcast: false,
                                                        )));
                                          },
                                          icon: Icon(
                                            Icons.notifications,
                                            color: themeColor,
                                          ),
                                          label: Text(
                                            "Notification",
                                            style: TextStyle(color: themeColor),
                                          )),
                                    ],
                                  ),
                                ],
                              ),
                            ),
                          ));
                    },
                  );
                }
              },
            );
          }
        }

What you have type in Search then that Data is shown in listview] 1

答案 2 :(得分:0)

这是一种非常简单的方法,可在“ snapshot.data.documents.map((DocumentSnapshot document)”中尝试此代码

if(_searchController.text.toString().contains(document['term'])){
  return new ListTile(
      title: new Text(document['term']),
    );
}