Flutter 如何在 Flutter 搜索过滤结果无结果时显示消息

Flutter How to show a message when flutter search filter result no result

我使用 TextFormField 过滤列表数组,使用 GridView 显示项目。在我的 TextFormField 中,我使用了 onChanged: onSearchTextChanged, 来过滤来自我在 json 中创建的 Rest API 的数组响应。过滤器工作正常,但我正在寻找一种方法来解决当用户输入过滤器内部不可用的过滤器时不显示结果的问题。下面是我的代码:

TextFormField如下:


TextFormField(

         controller: controller,
         keyboardType: TextInputType.text,
         onChanged: onSearchTextChanged,

             decoration: InputDecoration(
               border: InputBorder.none,

               contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
           prefixText: ' ',
           hintText: "Search",
           hintStyle: TextStyle(
               color: Colors.grey,fontWeight: FontWeight.normal,
               fontSize: 15,
               fontFamily:
               'Montserrat'),
           prefixIcon: Container(
               child:Icon(
                 Icons.search,
                 color: Colors.grey,
                   size: 20,
               )),

           suffixIcon: backClear==true?InkWell(
               onTap: () {
                 controller.clear();
                 onSearchTextChanged(
                     '');
               },
               child: Container(
                   child:Icon(
                     Icons.backspace,
                     color: Colors.grey,
                     size: 12,
                   ))): Container(
               child:Icon(
                 Icons.view_list_rounded,
                 color: Colors.grey,
                 size: 15,
               )),


           labelStyle: new TextStyle(color: Colors.grey),

         ),
       )

onSearchTextChanged 如下:


onSearchTextChanged(String text) async {
    _searchResult.clear();
    if (text.isEmpty) {
      setState(() {

        backClear=false;

      });
      return;
    }

    content.forEach((userDetail) {
      if (userDetail.username.toLowerCase().contains(text) || userDetail.username.toString().contains(text) ||
           userDetail.username.toUpperCase().contains(text)||userDetail.fullname.toLowerCase().contains(text) || userDetail.fullname.toString().contains(text) ||
           userDetail.fullname.toUpperCase().contains(text)||userDetail.phone.toLowerCase().contains(text) || userDetail.phone.toString().contains(text) ||
           userDetail.phone.toUpperCase().contains(text)||userDetail.email.toLowerCase().contains(text) || userDetail.email.toString().contains(text) ||
           userDetail.email.toUpperCase().contains(text) ) {
        _searchResult.add(userDetail);
      }

    });

    setState(() {

      backClear=true;


    });


  }

  


例如,如果 John 不是 username, fullname 的 return 数组列表的一部分,那么在屏幕上它应该显示一条消息说 not found

我的gridview如下:

Container(

      child: _searchResult.length != 0 ||
      controller.text.isNotEmpty
      ?new GridView.builder(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),

          itemCount: _searchResult == null ? 0 : _searchResult.length,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),
          itemBuilder: (BuildContext context, int index){

            return Card(
                elevation: 1,
                semanticContainer: true,
                child:InkWell(
                    onTap: () async {


                    },
                    child: Container(
                        padding: EdgeInsets.all(10),
                        child:Column(
                            crossAxisAlignment:
                            CrossAxisAlignment.start,
                            children: <Widget>[
                              Flexible(
                                child: Column(
                                  children: <Widget>[

                                    Stack(

                                      alignment: Alignment.bottomCenter,

                                      children: [
                                        CircleAvatar(
                                          radius: 30,
                                          backgroundColor: Colors.white,
                                          child: _searchResult[index].profile_img!=null?Container(
                                              padding: EdgeInsets.all(0),
                                              child:CircleAvatar(

                                                radius: 40,
                                                backgroundImage:NetworkImage(_searchResult[index].profile_img
                                                  ,),
                                                backgroundColor: Colors.white,
                                                //
                                              )):Container(
                                              padding: EdgeInsets.all(0),
                                              child:CircleAvatar(

                                                radius: 40,
                                                backgroundImage:AssetImage('assets/person_icon.png'),
                                                backgroundColor: Colors.white,
                                                //
                                              )),
                                        ),

                                      ],),



                                    Flexible(
                                        child:   Center(child: Text(_searchResult[index].username==null?"AppName":_searchResult[index].username,style: TextStyle(
                                          color: colorBlack,
                                          fontWeight: FontWeight.normal,
                                          fontSize: 10,
                                          fontFamily: 'Montserrat',
                                        ),))),


                                    Flexible(
                                      child:   Container(
                                        padding: EdgeInsets.only(left: 15,right: 15,top: 1,bottom: 1),
                                        decoration: BoxDecoration(
                                            color: colorBlue,borderRadius: BorderRadius.circular(3)),

                                        child: Text( "Follow",
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontWeight: FontWeight.bold,
                                            fontSize: 10,
                                            fontFamily: 'Montserrat',
                                          ),
                                        ),
                                      ),)

                                  ],
                                ),
                              ),
                            ]))));
            ;})

          :GridView.builder(
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),

          itemCount: content == null ? 0 : content.length,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),
          itemBuilder: (BuildContext context, int index){
            return Card(
                elevation: 1,
                semanticContainer: true,
                child:InkWell(
                    onTap: () async {


                    },
                    child: Container(
                        padding: EdgeInsets.all(10),
                        child:Column(
                            crossAxisAlignment:
                            CrossAxisAlignment.start,
                            children: <Widget>[
                              Flexible(
                                child: Column(
                                  children: <Widget>[

                                    Stack(

                                      alignment: Alignment.bottomCenter,

                                      children: [
                                        CircleAvatar(
                                          radius: 30,
                                          backgroundColor: Colors.white,
                                          child: content[index].profile_img!=null?Container(
                                              padding: EdgeInsets.all(0),
                                              child:CircleAvatar(

                                                radius: 40,
                                                backgroundImage:NetworkImage(content[index].profile_img
                                                  ,),
                                                backgroundColor: Colors.white,
                                                //
                                              )):Container(
                                              padding: EdgeInsets.all(0),
                                              child:CircleAvatar(

                                                radius: 40,
                                                backgroundImage:AssetImage('assets/person_icon.png'),
                                                backgroundColor: Colors.white,
                                                //
                                              )),
                                        ),

                                      ],),



                                    Flexible(
                                        child:   Center(child: Text(content[index].username==null?"AppName":content[index].username,style: TextStyle(
                                          color: colorBlack,
                                          fontWeight: FontWeight.normal,
                                          fontSize: 10,
                                          fontFamily: 'Montserrat',
                                        ),))),


                                    Flexible(
                                      child:   Container(
                                        padding: EdgeInsets.only(left: 15,right: 15,top: 1,bottom: 1),
                                        decoration: BoxDecoration(
                                            color: colorBlue,borderRadius: BorderRadius.circular(3)),

                                        child: Text( "Follow",
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontWeight: FontWeight.bold,
                                            fontSize: 10,
                                            fontFamily: 'Montserrat',
                                          ),
                                        ),
                                      ),)

                                  ],
                                ),
                              ),
                            ]))));}))

我不确定您在示例代码中实际显示结果的位置,但您可以实现的逻辑如下。 在 forEach 之后,您应该检查是否确实找到了某些结果,如果没有,将 showNotFoundText 设置为 true 以便在您的视图中显示消息。

onSearchTextChanged(String text) async {
    _searchResult.clear();
    if (text.isEmpty) {
      setState(() {
        backClear=false;
        showNotFoundText = false;
      });
      return;
    }

    content.forEach((userDetail) {
      if (userDetail.username.toLowerCase().contains(text) || userDetail.username.toString().contains(text) ||
           userDetail.username.toUpperCase().contains(text)||userDetail.fullname.toLowerCase().contains(text) || userDetail.fullname.toString().contains(text) ||
           userDetail.fullname.toUpperCase().contains(text)||userDetail.phone.toLowerCase().contains(text) || userDetail.phone.toString().contains(text) ||
           userDetail.phone.toUpperCase().contains(text)||userDetail.email.toLowerCase().contains(text) || userDetail.email.toString().contains(text) ||
           userDetail.email.toUpperCase().contains(text) ) {
        _searchResult.add(userDetail);
      }
    });

    if (_searchResult.isEmpty) {
      //Do something
      setState(() {
         showNotFoundText = true;
      });
    }

    setState(() {
      backClear=true;
    });

  }

在您的视图中添加类似的内容

showNotFoundText ? Text("No results found") : Container() //Empty container instead

由于你没有包含结果显示的代码,我是这样写的,但你也可以考虑直接在你的视图中使用这个逻辑:

_searchResult.isEmpty ? Text("No results found") : DisplayResultsWidget()

根据 Dani3le_ 的建议,在我的 onSearchTextChanged 中使用 add below if 语句,并且我在我的代码

上方声明了我的 bool showNotFoundText = false;
if (_searchResult.isEmpty) {
      //Do something
      setState(() {
         showNotFoundText = true;
      });
    }

在我的 Gridview 之上,我添加了以下内容以显示代码下方的 No result message 查找:

showNotFoundText==true ? Text("No result found!",style: TextStyle(fontFamily: 'Montserrat',color: Colors.grey, fontSize: 13, fontWeight: FontWeight.bold),) : Container(),

但是 onPress 的退格键 No result found 仍然显示,即使输入在搜索列表中可用所以我将 showNotFoundText = false; 添加到 setState() 这样每次按下退格键将 showNotFoundText 的状态设置回 false,如下所示:

setState(() {
        showNotFoundText = false;

 });