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

Flutter中Bottom Modal Sheet的GridItem选中状态持久化问题

解决Flutter Bottom Modal Sheet中GridItem选中状态不持久的问题

问题核心在于GridItem内部维护的选中状态没有和外部的selectedCache同步初始化——每次打开模态框,GridItem的isSelected都会被重置为false,完全忽略了之前已经选中的项。下面是具体修复方案:

步骤1:修改GridItem组件,支持传入初始选中状态

让GridItem从外部接收初始选中状态,而非硬编码默认值,同时保留点击切换逻辑:

class GridItem extends StatefulWidget {
  final String item;
  final ValueChanged<bool> isSelected;
  // 新增:接收初始选中状态参数
  final bool initialIsSelected;

  GridItem({
    required this.item,
    required this.isSelected,
    required this.initialIsSelected,
  });

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

class _GridItemState extends State<GridItem> {
  late bool isSelected;

  @override
  void initState() {
    super.initState();
    // 用外部传入的初始状态初始化组件内部状态
    isSelected = widget.initialIsSelected;
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(5,5,5,5),
      child: GestureDetector(
        child: Container(
            decoration: BoxDecoration(
              border: Border.all(
                color: isSelected ? Colors.lightGreenAccent : Colors.grey,
                width: 2,
              ),
              borderRadius: BorderRadius.circular(12.0),
            ),
            child:InkWell(
              onTap: () {
                setState(() {
                  isSelected = !isSelected;
                  widget.isSelected(isSelected);
                });
              },
              child: Stack(
                children: <Widget>[
                  Center(child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(widget.item),
                  )),
                  isSelected
                      ? const Padding(
                        padding: EdgeInsets.fromLTRB(3, 3, 0 , 0),
                        child: Icon(
                            Icons.check_circle,
                            color: Colors.green,
                            size: 15.0,
                        ),
                      )
                      : Container()
                ],
              ),
            )
        )
      ),
    );
  }
}

步骤2:在模态框的GridView中传入初始选中状态

创建GridItem时,判断当前项是否在selectedCache中,将结果作为initialIsSelected传入:

GridView.builder(
  scrollDirection: Axis.vertical,
  shrinkWrap: true,
  gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
      maxCrossAxisExtent: 200
  ),
  itemCount: comList.length,
  itemBuilder: (BuildContext c,int index){
    final currentItem = comList[index];
    // 判断当前项是否已被选中,作为初始状态传入
    final isInitiallySelected = selectedCache.contains(currentItem);
    return GridItem(
        item: currentItem,
        initialIsSelected: isInitiallySelected,
        isSelected: (bool value){
          setState(() {
            if(value){
              selectedCache.add(currentItem);
            } else{
              selectedCache.remove(currentItem);
            }
          });
        });
  }
),

关键注意点

  • 确保selectedCache是页面State类的成员变量(不要在_bottomSheet方法内临时创建),这样关闭模态框后选中数据不会丢失。
  • 现在选中状态完全由外部的selectedCache统一管理,GridItem只负责展示和回调点击事件,避免了之前内部状态和外部状态冲突的问题。

内容的提问来源于stack exchange,提问作者Sharvan Kumaran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:15:02