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

Flutter同一Column放置两个ListView无法正常运行问题求助

核心结论

不需要将所有组件改为Stateful,仅需将承载列表状态的上层HomeView组件改为Stateful即可,子组件保持Stateless,通过回调函数将点击事件传递到上层执行setState更新列表,即可触发两个ListView的刷新。

现有代码问题梳理
  • 错误定义State类:_WidgetOneState、_WidgetTwoState错误继承了StatelessWidget,还保留了仅StatefulWidget才需要的createState方法,逻辑完全错误
  • 未触发UI更新:修改全局列表后没有调用setState,Flutter感知不到状态变化,不会触发UI刷新
  • 点击逻辑错误:WidgetBlue的点击逻辑仅删除列表最后一个元素,没有删除当前点击元素,也没有将元素添加到绿色列表
  • 不合理使用全局变量:列表状态全局存储容易造成状态污染,不符合Flutter状态管理规范
完整可运行修正代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const HomeView(),
      themeMode: ThemeMode.system,
    );
  }
}

// HomeView改为StatefulWidget,统一管理两个列表的状态
class HomeView extends StatefulWidget {
  const HomeView({super.key});

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  // 列表状态放在State内部管理
  final List<int> blueList = [1,2,3,4,5,6,7,8];
  final List<int> greenList = [];

  // 蓝色色块点击逻辑:把选中元素从蓝列表移到绿列表
  void onTapBlue(int value) {
    setState(() {
      blueList.remove(value);
      greenList.add(value);
    });
  }

  // 绿色色块点击逻辑:按需实现把元素移回蓝列表的逻辑
  void onTapGreen(int value) {
    setState(() {
      greenList.remove(value);
      blueList.add(value);
    });
  }

  @override 
  Widget build(BuildContext context) {
    return Scaffold( 
      appBar: AppBar(title: const Text("Demo App"),),
      body: SafeArea( 
        child: Column(
          children: [
            // 把列表数据和点击回调传递给子组件
            WidgetOne(blueList: blueList, onTapBlue: onTapBlue),
            WidgetTwo(greenList: greenList, onTapGreen: onTapGreen),
          ],
        )
      ),
    );
  }
}

// 子组件保持Stateless,仅负责展示和事件透传
class WidgetOne extends StatelessWidget {
  final List<int> blueList;
  final Function(int) onTapBlue;
  const WidgetOne({super.key, required this.blueList, required this.onTapBlue});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: ListView.builder(
        itemBuilder: (ctx, idx) => WidgetBlue(value: blueList[idx], onTap: onTapBlue), 
        itemCount: blueList.length
      )
    );
  }
}

class WidgetTwo extends StatelessWidget {
  final List<int> greenList;
  final Function(int) onTapGreen;
  const WidgetTwo({super.key, required this.greenList, required this.onTapGreen});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: ListView.builder(
        itemBuilder: (ctx, idx) => WidgetGreen(value: greenList[idx], onTap: onTapGreen), 
        itemCount: greenList.length
      )
    );
  }
}

class WidgetBlue extends StatelessWidget {
  final int value;
  final Function(int) onTap;
  const WidgetBlue({super.key, required this.value, required this.onTap});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () => onTap(value),
      child: Center(
        child: Container(
          margin: const EdgeInsets.symmetric(vertical: 8),
          color: Colors.blue,
          height: 50,
          width: 90,
          child: Center(child: Text("$value", style: const TextStyle(color: Colors.white))),
        ),
      ),
    );
  }
}

class WidgetGreen extends StatelessWidget {
  final int value;
  final Function(int) onTap;
  const WidgetGreen({super.key, required this.value, required this.onTap});

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () => onTap(value),
      child: Center(
        child: Container(
          margin: const EdgeInsets.symmetric(vertical: 8),
          color: Colors.green,
          height: 50,
          width: 90,
          child: Center(child: Text("$value", style: const TextStyle(color: Colors.white))),
        ),
      ),
    );
  }
}
实现逻辑说明
  • 状态上浮:列表的增删修改逻辑全部放在上层HomeView的State中管理,子组件只负责接收数据展示、接收用户操作透传事件
  • setState触发刷新:只有StatefulWidget的State类中可以调用setState方法,调用后Flutter会重新执行build方法,传入新的列表数据给子组件,两个ListView会自动基于新数据刷新展示内容

内容的提问来源于stack exchange,提问作者Dmitry Bubnenkov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:45:04