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

如何修复Flutter中ListView.builder列表项自动变更位置的问题

Flutter ListView.builder列表项自动错位修复方案

核心问题原因

  • FutureBuilder的future配置错误,导致接口重复请求。你直接将getSchedule()作为future参数传入,每次页面重绘(系统触发的状态更新、屏幕亮度变化等场景都会触发重绘)都会重新调用接口拉取数据,接口返回的比赛列表顺序发生变化后,setState更新就会触发列表错位。
  • 列表项缺少唯一key,Flutter无法正确识别列表元素身份。当数据更新时,ListView无法对应新旧列表项的位置,就会出现渲染错乱。
  • itemBuilder逻辑错误。你在itemBuilder中判断单条数据不是UPCOMING状态时,返回了全局提示文本,而非空占位组件,会导致列表长度和渲染项不匹配,加剧位置错乱。
  • 额外拼写问题:你导入http库时定义的别名为HTTP,实际调用时用的是小写http,会触发编译错误,建议统一改为小写别名:import 'package:http/http.dart' as http;

具体修复步骤

  1. 缓存Future请求,避免重复调用接口
    在_SeriesSchedulePageState类中新增缓存变量,初始化时仅执行一次请求:
class _SeriesSchedulePageState extends State<SeriesSchedulePage> {
  List<dynamic> matches = [];
  var match;
  // 新增缓存变量
  late Future scheduleFuture;

  @override
  void initState() {
    super.initState();
    // 初始化时仅执行一次请求,缓存结果
    scheduleFuture = getSchedule();
  }
  // 其余原有代码不变
}

修改FutureBuilder的future参数为缓存的变量:

FutureBuilder(
  future: scheduleFuture,
  // 其余原有参数不变
)
  1. 给列表项添加唯一key,让Flutter正确识别元素
    推荐使用数据中自带的唯一比赛ID作为key,没有的话可以临时用ValueKey(index)过渡:
// 给Card组件添加key属性
return Card(
  key: ValueKey(matches[index]['matchId']), // 替换为你数据中对应的唯一ID字段名
  elevation: 2,
  // 其余原有属性不变
);
  1. 修正列表渲染逻辑,提前过滤数据
    先在接口请求中过滤出所有UPCOMING状态的比赛,全局提示移到列表外层:
getSchedule() async {
  http.Response response = await http
      .get(Uri.parse("https://api.cricket.com.au/matches/2780"));
  final Map parseData = await json.decode(response.body.toString());
  List allMatches = parseData['matchList']["matches"];
  // 提前过滤出状态为UPCOMING的比赛
  matches = allMatches.where((item) => item["status"] == "UPCOMING").toList();
  setState(() {
    match = matches;
  });
}

// 修改FutureBuilder的builder逻辑
builder: (context, snapshot) {
  if (match == null) {
    return Center(
        child: CupertinoActivityIndicator(
            animating: true, radius: 15));
  } else if(matches.isEmpty) {
    // 仅当无符合条件的比赛时,才显示全局提示
    return Center(
      child: Text("No Upcoming Match in this series"),
    );
  } else {
    return ListView.builder(
        itemCount: matches.length,
        shrinkWrap: true,
        reverse: false,
        itemBuilder: (context, index) {
          // 移除原有状态判断,直接返回卡片组件
          return Card(
            key: ValueKey(matches[index]['matchId']),
            elevation: 2,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(7),
            ),
            // 其余原有Card代码不变
          );
        }
    );
  }
}

内容的提问来源于stack exchange,提问作者Haseeb Ahmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:06:02