繁体   English   中英

为什么我的列表在 Flutter 中使用 setState 时没有更新

[英]Why my list is not updating while using setState in Flutter

我在我的文件中制作了一个OriginDestination类的列表,即_allCities 然后我分配了所有值filteredCitiescitiesinitState

然后我做了一个函数 runFilter ,它会从 TextField 中获取关键字并相应地过滤结果并将它们保存到resultCities 然后我使用resultCitiesListView.builder显示信息。 但问题是,该列表没有根据我正在搜索的关键字进行过滤。

此外,如果您能提出更好的使用参数城市的方法,我将不胜感激,即我不认为将cities作为参数通过状态的构造函数传递是一种很好的做法。

这是代码 -

import 'package:flutter/material.dart';
import 'package:passenger_flutter_app/models/new_city.dart';
import 'package:passenger_flutter_app/models/origin_destination.dart';
import 'package:passenger_flutter_app/utils/colors.dart';


class SelectionScreen extends StatefulWidget {

  List<OriginDestination>? cities;

  SelectionScreen({this.cities});

  @override
  _SelectionScreenState createState() => _SelectionScreenState(cities);
}

class _SelectionScreenState extends State<SelectionScreen> {
  final List<OriginDestination>? _allCities;

  _SelectionScreenState(this._allCities);

  bool originSelected=false;
  List<OriginDestination>? resultCities = [];
  List<OriginDestination>? filteredCities = [];

  void getCitiesFromResponse() {
    /*for(var city in _allCities!) {
      cities!.add(city.origin!);
    }*/
    filteredCities=_allCities;
    resultCities=_allCities;
  }

  @override
  initState() {
    // at the beginning, all users are shown
    getCitiesFromResponse();
    super.initState();
  }

  void _runFilter(String enteredKeyword) {
    if (enteredKeyword.isEmpty) {
      // if the search field is empty or only contains white-space, we'll display all users
      filteredCities = _allCities;
    } else {
      filteredCities = _allCities!
          .where((city) =>
          city.origin!.name!.toLowerCase().contains(enteredKeyword.toLowerCase()))
          .toList();
      // we use the toLowerCase() method to make it case-insensitive
    }

    @override
    void setState() {
      resultCities=filteredCities;
    }
  }


  @override
  Widget build(BuildContext context) {
    var originSelected;
    return SafeArea(
      child: Scaffold(
        backgroundColor: const Color(0xffEEEDEF),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10.0),
              child: Column(
                children: [
                  Container(
                    width: MediaQuery.of(context).size.width*0.8,
                  ),
                  Row(
                    children: [
                      IconButton(
                        icon: const Icon(Icons.arrow_back),
                        color: Colors.orange,
                        onPressed: () {
                          Navigator.pop(context);
                        },
                      ),
                      Column(
                        children: [
                          originSelected==true ? Container(
                            child: Text(''),
                          ) :
                          Container(
                            width: MediaQuery.of(context).size.width * 0.85,
                            height: 50.0,
                            decoration: BoxDecoration(
                                color: Colors.white,
                                borderRadius:
                                const BorderRadius.all(Radius.circular(5.0)),
                                border: Border.all(color: colorAccent)),
                            child: TextField(
                              decoration: InputDecoration(
                                hintText: "Enter Origin",
                                border: InputBorder.none,
                                contentPadding: const EdgeInsets.only(left: 10.0),
                                hintStyle: TextStyle(
                                  fontSize: 15.0,
                                  color: Colors.grey[500],
                                ),
                              ),
                              onChanged: (value) {
                                _runFilter(value);
                              },
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ),
            Align(
              alignment: Alignment.centerLeft,
              child: Padding(
                padding: EdgeInsets.only(
                    left: MediaQuery.of(context).size.width * 0.04, top: 3.0),
                child: Text(
                  'Popular Searches:',
                  style: TextStyle(
                      color: popUpLightTextColor,
                      fontSize: MediaQuery.of(context).size.width * 0.035),
                ),
              ),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: resultCities!.length,
                itemBuilder: (context, index) {
                  return Padding(
                    padding: EdgeInsets.only(
                        left: 18.0, top: index==0 ? 29.0 : 15.0, bottom: 15.0),
                    child: InkWell(
                      onTap: () {
                        print(resultCities?[index].origin!.name);
                        /*setState(() {
                          widget.city=filteredCities[index]['city'];
                          print("Changed to - ");
                          //print(widget.city);
                          Navigator.pop(context);
                        });*/
                      },
                      child: Text(
                        resultCities?[index].origin!.name??"No name",
                        style: const TextStyle(
                          color: darkText,
                          fontSize: 15.0,
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

好像你定义了 setState 函数而不是调用它,所以而不是:

@override
void setState() {
    resultCities=filteredCities;
}

写:

setState(() {
    resultCities=filteredCities;
});

为什么要覆盖 setState。 您还可以将回调作为 setState 中的参数传回。

您应该在触发器上调用 setState,例如手势或按钮:

setState(() => resultCities = filteredCities);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM