You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用setState时列表不更新及参数传递优化问题

问题修复方案

一、搜索过滤失效问题解决

你代码中搜索不生效的核心原因是错误重写了setState方法而非调用框架自带的setState触发UI更新:你在_runFilter内部定义了一个带有@override的局部setState方法,这个方法不会被自动执行,resultCities更新后UI无法重绘,因此列表永远展示初始数据。

二、State构造传参优化

Flutter官方不推荐通过State构造函数传递参数,State类可以直接通过widget属性访问所属StatefulWidget的所有公开成员,直接调用widget.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 {
  final List<OriginDestination>? cities;
  const SelectionScreen({super.key, this.cities});

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

class _SelectionScreenState extends State<SelectionScreen> {
  bool originSelected = false;
  List<OriginDestination> resultCities = [];

  void getCitiesFromResponse() {
    resultCities = widget.cities ?? [];
  }

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

  void _runFilter(String enteredKeyword) {
    List<OriginDestination> tempList = [];
    if (enteredKeyword.trim().isEmpty) {
      tempList = widget.cities ?? [];
    } else {
      tempList = widget.cities!
          .where((city) => city.origin?.name?.toLowerCase()
                  .contains(enteredKeyword.toLowerCase()) ?? false)
          .toList();
    }
    setState(() {
      resultCities = tempList;
    });
  }

  @override
  Widget build(BuildContext context) {
    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
                              ? const SizedBox.shrink()
                              : 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(
                  '热门搜索:',
                  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("已修改为 - ");
                          Navigator.pop(context);
                        });*/
                      },
                      child: Text(
                        resultCities[index].origin?.name ?? "无名称",
                        style: const TextStyle(
                          color: darkText,
                          fontSize: 15.0,
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

优化点说明

  • 删掉了冗余的_allCities、filteredCities变量,减少内存占用
  • 修复了setState调用逻辑,过滤后自动刷新UI
  • 去掉了State构造传参的不合理写法,直接通过widget.cities获取父组件参数
  • 空安全判断优化,避免空指针异常
  • 删掉了build方法中重复定义的originSelected局部变量,避免逻辑覆盖

内容的提问来源于stack exchange,提问作者Shreyansh Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 02:45:03