0

我有一个填充了 Future 构建器的列表。这些项目已从 API 的列表中正确加载。以下是代码的相关部分。我textfield在应用栏中有一个,我想用它来过滤列表。

 List newList = List();
 List originalList = List();
 bool _showSearchBox = false;
 TextEditingController _textController = TextEditingController();
 Future _future;

 @override
  void initState() {
    _future = commonApiProvider.fetchUserList(offset, widget.selectedDate);
    super.initState();
  }

   @override
  Widget build(BuildContext context) {
    size = Screen(MediaQuery.of(context).size);
    loadMoreNewStatus = ItemLoadMoreStatus.LOADING;
    return Scaffold(
      backgroundColor: Color(0xfff0f0f0),
      appBar: AppBar(
        automaticallyImplyLeading: _showSearchBox == true ? false : true,
        backgroundColor: CustomColors.absentTileColor,
        elevation: 1,
        title:
            _showSearchBox == true ? _buildSearchWidget() : Text("Absent List"),
        actions: <Widget>[
          _showSearchBox == false ? _buildSearchIcon() : Container(),
        ],
      ),
      body: FutureBuilder(
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.none &&
              snapshot.hasData == null) {
            return Text("Records not found for selected date.");
          } else if (snapshot.hasData) {
            return _buildListChild(snapshot);
          } else if (snapshot.hasError) {
            return Text(snapshot.error.toString());
          }
        },
        future: _future,
      ),
    );
  }

   Widget _buildListChild(AsyncSnapshot snapshot) {
    var data = snapshot.data.d;
    newList = json.decode(data.userList);
    originalList = json.decode(data.userList);


    return RefreshIndicator(
      key: _refreshIndicatorKey,
      child: NotificationListener(
        onNotification: onNotificationHandler,
        child: ListView.builder(
            padding: EdgeInsets.only(top: size.getSizePx(10)),
            scrollDirection: Axis.vertical,
            shrinkWrap: true,
            physics: const BouncingScrollPhysics(),
            itemCount: newList.length,
            controller: scrollContainer,
            itemBuilder: (context, index) {
              if (index == newList.length) {
                return _buildProgressIndicator();
              } else {
                loadMoreNewStatus = ItemLoadMoreStatus.STABLE;

                animationController.forward();

                return cardView(newList[index]);
              }
            }),
      ),
      onRefresh: _refreshStuffs,
    );
  }

  Widget cardView(userList){
    //build list items here.
  }

  bool onNotificationHandler(ScrollNotification notification){
    //stuffs here
  }

  _refreshStuffs(){
    //code to refresh list.
  }

   Widget _buildSearchWidget(){
     return Container(
        child: TextField(
              controller: _textController,
              style: TextStyle(fontSize: 14.0, color: Colors.grey[800]),
              onChanged: onSearchTextChanged,
          );
     );
   }


   onSearchTextChanged(String text) async {
    List tempSearchList = List();
    tempSearchList.addAll(originalList);

    if (text.isNotEmpty) {
      List tempListData = List();

      tempSearchList.forEach((item) {
        String empName = item["empname"];

        if (empName.toLowerCase().contains(text.toLowerCase())) {
          tempListData.add(item);
        }
      });

      setState(() {
        newList.clear();
        newList.addAll(tempListData);
      });
      return;
    } else {
      setState(() {
        newList.clear();
        newList.addAll(originalList);
      });
    }
  }

问题

问题是上面的代码不起作用,列表根本没有改变。如果我调试方法onSearchTextChanged,它工作得很好。我也已经清除newList了这种方法,但似乎不起作用。任何人都可以帮助如何实现过滤器?

4

1 回答 1

0

这里的想法是:一旦 FutureBuilder 完成,它就不会重建。我希望下面的代码有所帮助。让我知道您的问题是否存在。

class _MyHomePageState extends State<MyHomePage> {
  var items = [];

 @override
  void initState() {
    callApi();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: YourFilteringTextField(),
      ),
      body: ListView.builder(
        itemBuilder: (context, position) {
          return Text(items[position]);
        },
        itemCount: items.length,
      ),
    );
  }

  callApi() {
    //call api to get your latest items
    setState(() {
      //   items= itemsFetchedFromApi;
    });
  }

  filter(query) {
    //applyFilter
    setState(() {
      //   items= itemsAfterFiltering;
    });
  }
}
于 2020-03-18T15:52:26.487 回答