简体   繁体   中英

Why my list is not updating while using setState in Flutter

I made a list of class OriginDestination , ie _allCities in my file. I then assigned all values in filteredCities and cities in initState .

Then I made a function runFilter which would take keyword from TextField and filter the results accordingly and save them to resultCities . Then I am using resultCities to display the information in ListView.builder . But the problem is, the list is not filtering according to the keyword i am searching.

Also, it would be appreciated if you can suggest a better way of using parameter cities, ie I don't think that passing the cities as parameter through state's constructor is a good practice.

Here is the code -

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

seems like you defined the setState function instead of calling it, so instead of:

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

write:

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

Why are you overriding the setState. You also pass the call back as argument in the setState.

You should be call setState on a trigger, like a gesture or button:

setState(() => resultCities = filteredCities);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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