首页 > 解决方案 > 在 Flutter 中使用 FutureBuilder 进行 ListView 过滤器搜索

问题描述

我是颤振编程的初学者。当我使用future builder时,listview的搜索功能出现问题,当我输入一个字母时,它会在一秒钟内更改列表,但在一秒钟后返回所有列表数据。我不知道是什么错误,因为只有没有警告或错误。我堆在这段代码上,请帮助ppppppppppppppp......

这是我的代码, 输入字母时的默认列表数据 ,几秒钟后再次返回列表

List mydata;
  List unfilterData;

  Future loadJsonData() async {
    List data = json.decode(await rootBundle.loadString('Json/indomodel.json'));
    setState(() {
      mydata = data;
      this.unfilterData = mydata;
    });
    return data;
  }

  Widget mylist() {
    return FutureBuilder(
      future: loadJsonData(),
      builder: (context, snapshot) {
        if (!snapshot.hasData)
          return Center(
              child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation(Colors.amber),
          ));
        else {
          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext context, index) {
              return Card(
                elevation: 0.3,
                child: ListTile(
                  // leading: CircleAvatar(child: Icon(FontAwesomeIcons.adjust),),
                  title: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          SelectableText(
                            mydata[index]['word'],
                            // data[index]['word'],
                            style: TextStyle(
                                fontSize: 16.0,
                                fontWeight: FontWeight.bold,
                                color: Colors.deepPurple.shade800),
                          ),
                          Text(
                            "My Kamus",
                            style: TextStyle(color: Colors.grey, fontSize: 10),
                          )
                        ],
                      ),
                      SizedBox(
                        height: 10.0,
                      ),
                      Text(
                        mydata[index]['trans'],
                        style: TextStyle(
                            color: Colors.grey.shade700, fontSize: 13.0),
                      )
                    ],
                  ),
                ),
              );
            },
          );
        }
      },
    );
  }

  searchData(str) {
    var strExist = str.length > 0 ? true : false;

    if (strExist) {
      var filterData = [];

      for (var i = 0; i < unfilterData.length; i++) {
        String word = unfilterData[i]['word'];
        if (word.contains(str)) {
          filterData.add(unfilterData[i]);
        }
      }

      setState(() {
        this.mydata = filterData;
      });
    } else {
      setState(() {
        //
        this.mydata = this.unfilterData;
      });
    }
  }

标签: flutterdart

解决方案


您的代码中的问题是您正在调用loadJsonData()FutureBuilder因此当您调用时setState()loadJsonData()再次调用。

您应该做的是在 中调用loadJsonData()一次,initState()将未来保存到一个变量中并在 上使用该变量FutureBuilder,如下所示:

Future _future;

@override
void initState() {
  super.initState();
  _future = loadJsonData();
}

FutureBuilder这样做:

future: _future,

注意:由于您需要过滤列表,因此可以将列表保存到mydata然后mydata在 中使用ListView.builder(),只需确保更改此部分以避免混淆:

itemCount: snapshot.data.length,

应该:

itemCount: mydata.length,

建议:

  • 指定正确的类型是一个很好的做法,Future因此List 您可以在没有警告的情况下访问属性,在您的情况下将是这样的:Future<List<Map<String, dynamic>>>List<Map<String, dynamic>>.
  • 从未来调用是不好的,setState()因为小部件可能会被释放并导致错误,您可以将列表设置在 FutureBuilder.

推荐阅读