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

Flutter实现居中不可滚动水平ListView.builder方案问询

解决方案

要实现居中、固定不可滚动的水平选项栏,核心是调整组件布局逻辑并修正单选按钮的参数错误,以下是两种可行方案:

方案一:用Row替代ListView.builder(适合固定数量子项)

既然你明确子项数量为5,直接用Row包裹所有子项更简洁,配合Center组件实现整体居中:

if (snapshot.hasData) {
  return Center( // 让整个选项栏居中显示
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center, // 子项之间均匀分布
      children: List.generate(5, (index) {
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8.0), // 子项间添加间距
          child: Column(
            children: [
              CustomRadio(
                // 修正单选参数:groupValue是当前选中的全局值,value是当前子项对应的值
                groupValue: widget.answer,
                onChanged: (value) {
                  setState(() {
                    widget.answer = snapshot.data!.questions[3].answers![index].value;
                  });
                },
                value: snapshot.data!.questions[3].answers![index].value,
              ),
              SizedBox(
                height: 34,
                width: 56,
                child: Text(
                  snapshot.data!.questions[3].answers![index].text,
                  textAlign: TextAlign.center,
                  maxLines: 2,
                  style: GoogleFonts.openSans(
                    textStyle: const TextStyle(
                      color: Color(0xff000000),
                      letterSpacing: -0.26,
                      fontSize: 12,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }),
    ),
  );
}

方案二:基于ListView.builder修改(保留原组件结构)

如果坚持使用ListView.builder,需做以下3处调整:

  1. 禁用滚动物理
  2. 给容器设置足够宽度以容纳所有子项
  3. 外层包裹Center实现居中
if (snapshot.hasData) {
  return Center(
    child: SizedBox(
      height: 70,
      // 计算总宽度:5个子项*(56文本宽度+16左右padding),或直接取屏幕宽度的90%
      width: 5 * (56 + 16),
      child: ListView.builder(
        scrollDirection: Axis.horizontal,
        physics: const NeverScrollableScrollPhysics(), // 禁用滚动
        itemCount: 5,
        itemBuilder: (context, index) {
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8.0),
            child: Column(
              children: [
                CustomRadio(
                  groupValue: widget.answer,
                  onChanged: (value) {
                    setState(() {
                      widget.answer = snapshot.data!.questions[3].answers![index].value;
                    });
                  },
                  value: snapshot.data!.questions[3].answers![index].value,
                ),
                SizedBox(
                  height: 34,
                  width: 56,
                  child: Text(
                    snapshot.data!.questions[3].answers![index].text,
                    textAlign: TextAlign.center,
                    maxLines: 2,
                    style: GoogleFonts.openSans(
                      textStyle: const TextStyle(
                        color: Color(0xff000000),
                        letterSpacing: -0.26,
                        fontSize: 12,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          );
        },
      ),
    ),
  );
}

关键错误修正

你原代码中CustomRadio的参数逻辑完全颠倒:groupValue应该是当前选中的全局值(widget.answer),value是当前子项对应的选项值,这样单选按钮才能正确识别选中状态。

内容的提问来源于stack exchange,提问作者Juan Torres

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:33:21