在Flutter中使用FutureBuilder进行ListView过滤器搜索

时间:2019-10-12 04:06:45

标签: flutter dart

我是Flutter编程的初学者。当我使用Future Builder时,我遇到了listview的搜索功能问题,当我键入一个字母时,它会改变列表一秒钟,但在一秒钟后又回到所有列表数据。我不知道这是什么错误,因为没有警告或错误而已。我在此代码上堆叠,请帮助ppppppppppppppppp ......

这是我的代码, Default list data when i type letters, the list back again after a seconds

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;
      });
    }
  }

1 个答案:

答案 0 :(得分:1)

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

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

Future _future;

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

然后在FutureBuilder中执行以下操作:

future: _future,

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

itemCount: snapshot.data.length,

应为:

itemCount: mydata.length,

建议:

  • FutureList指定正确的类型是一个好习惯 这样就可以在没有警告的情况下访问属性 可能是这样的:Future<List<Map<String, dynamic>>>List<Map<String, dynamic>>
  • 以后再致电setState()不好,因为该小部件 可能会被处理并导致错误,您可以在 FutureBuilder