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

Flutter中为ListView添加前后切换按钮及组件推荐

自定义横向滚动数字选择器:按钮控制实现与组件推荐

一、添加前后滚动按钮的实现方案

利用你已有的ScrollController(_controller2)即可控制ListView的滚动定位,结合状态变量同步选中项的样式变化,具体实现如下:

核心步骤

  1. 定义状态变量跟踪选中项:
int _selectedIndex = 0;
final ScrollController _controller2 = ScrollController();
  1. 用Row包裹滚动视图与左右按钮,通过animateTo方法控制滚动偏移:
Row(
  children: [
    // 左按钮:滚动到上一项
    IconButton(
      icon: const Icon(Icons.arrow_back_ios),
      onPressed: () {
        if (_selectedIndex > 0) {
          setState(() => _selectedIndex--);
          _controller2.animateTo(
            _selectedIndex * 46, // 46为单个item的总宽度(容器宽+margin)
            duration: const Duration(milliseconds: 300),
            curve: Curves.ease,
          );
        }
      },
    ),
    Expanded(
      child: FadingEdgeScrollView.fromScrollView(
        gradientFractionOnEnd: 0.2,
        gradientFractionOnStart: 0.15,
        child: ListView.builder(
          controller: _controller2,
          scrollDirection: Axis.horizontal,
          itemBuilder: (BuildContext context, int index) {
            int one = index + 1;

            Color colorWhat(int q) => q == _selectedIndex ? const Color(0xff0AFF6C) : Colors.white;
            double sizeOfCircle(int qq) => qq == _selectedIndex ? 27 : 22;
            double sizeOfCircleText(int qqq) => qqq < 10 ? 13.9 : 13.7;

            return GestureDetector(
              child: Row(
                children: [
                  Container(
                    alignment: Alignment.center,
                    width: sizeOfCircle(index),
                    margin: const EdgeInsets.fromLTRB(2, 0, 17, 0),
                    decoration: BoxDecoration(
                      color: colorWhat(index),
                      shape: BoxShape.circle,
                      boxShadow: const [
                        BoxShadow(offset: Offset(0, 5), blurRadius: 10.0, spreadRadius: -7),
                      ],
                    ),
                    child: Text(
                      one.toString(),
                      style: TextStyle(
                        fontWeight: FontWeight.w600,
                        fontSize: sizeOfCircleText(index),
                      ),
                    ),
                  ),
                ],
              ),
              onTap: () {
                setState(() => _selectedIndex = index);
                _controller2.animateTo(
                  index * 46,
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.ease,
                );
                Scaffold.of(context).showSnackBar(
                  SnackBar(content: Text((index+1).toString())),
                );
              },
            );
          },
          itemCount: 100,
        ),
      ),
    ),
    // 右按钮:滚动到下一项
    IconButton(
      icon: const Icon(Icons.arrow_forward_ios),
      onPressed: () {
        if (_selectedIndex < 99) {
          setState(() => _selectedIndex++);
          _controller2.animateTo(
            _selectedIndex * 46,
            duration: const Duration(milliseconds: 300),
            curve: Curves.ease,
          );
        }
      },
    ),
  ],
)

二、第三方组件包推荐

如果不想手动实现,以下组件可直接满足需求:

  • numberpicker:专门的数字选择器,支持横向/纵向布局,可自定义外观样式
  • flutter_xlider:支持滚动选择的滑块组件,适配数字场景,样式高度可定制
  • scrollable_positioned_list:官方维护的列表组件,支持精确控制滚动位置,适合需要精准跳转的场景

内容的提问来源于stack exchange,提问作者seyyed javad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:25:06