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

Flutter实现参考图式特殊列表滚动效果求助

实现方案

要实现你需要的效果(选中项与相邻项间距更大、选中项为白色其余项为灰色),可以通过动态控制item的间距和颜色来实现,修改后的代码如下:

int selectedIndex = 15; // 初始选中索引

@override
Widget build(BuildContext context) {
  return Stack(
    children: [
      // 保留原有的上下横线背景
      Positioned.fill(
        child: SizedBox(
          height: 60,
          width: 200,
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  width: 70,
                  height: 4,
                  decoration: const BoxDecoration(
                    color: kPrimary500,
                  ),
                ),
                const SizedBox(height: 100),
                Container(
                  width: 70,
                  height: 4,
                  decoration: const BoxDecoration(
                    color: kPrimary500,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
      Container(
        padding: const EdgeInsets.only(top: 40, bottom: 40),
        child: ListWheelScrollView.useDelegate(
          controller: FixedExtentScrollController(initialItem: selectedIndex),
          itemExtent: 50, // 基础item高度
          perspective: 0.005, // 调整透视效果,避免极端值导致的异常
          diameterRatio: 1.6,
          physics: const FixedExtentScrollPhysics(),
          squeeze: 0.8, // 调整挤压系数,让非选中项布局更紧凑
          useMagnifier: true,
          magnification: 1.2, // 适度放大选中项,保证视觉自然
          onSelectedItemChanged: (index) {
            setState(() {
              selectedIndex = index;
              currentSelection = selection[index];
            });
          },
          childDelegate: ListWheelChildLoopingListDelegate(
            children: List<Widget>.generate(selection.length, (index) {
              // 计算当前item与选中项的距离
              final int distance = (selectedIndex - index).abs();
              // 设置颜色:仅选中项为白色,其余为灰色
              final Color tileColor = selectedIndex == index ? kWhite : Colors.grey;
              // 给选中项的相邻项添加额外间距
              EdgeInsets padding = EdgeInsets.zero;
              if (distance == 1) {
                // 上相邻项增加顶部padding
                if (index > selectedIndex) {
                  padding = const EdgeInsets.only(top: 15);
                }
                // 下相邻项增加底部padding
                else {
                  padding = const EdgeInsets.only(bottom: 15);
                }
              }
              return Padding(
                padding: padding,
                child: ScrollTile(
                  selection: selection[index].toString(),
                  selectedColor: tileColor,
                ),
              );
            }),
          ),
        ),
      ),
    ],
  );
}

关键修改说明

  • 动态间距控制:通过判断当前item与选中项的距离,给相邻项添加额外padding,实现选中项与相邻项的间距大于其他项之间的间距。
  • 颜色逻辑优化:直接根据是否为选中项设置颜色,确保只有选中项显示白色,其余项统一为灰色。
  • 参数调整:修改perspective、squeeze、magnification等参数,让滚动和放大效果更自然,避免极端值导致的视觉异常。
  • 索引跟踪优化:新增selectedIndex变量直接跟踪选中项的索引,更便捷地判断item与选中项的关系。

若你的ScrollTile组件需要根据传入的颜色调整文本样式,确保内部的Text组件使用传入的selectedColor即可。

内容的提问来源于stack exchange,提问作者Matei Megyesi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:25:36