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

如何用Flutter实现单可见项、可按钮控制的水平语言选择列表?

实现横向滚动语言选择组件的方案

一、现成可用的第三方包

  • flutter_swiper_null_safety:支持自定义卡片样式、自动居中选中、滚动吸附效果,完美匹配你要的交互。配置时只需关闭循环(loop: false)、设置合适的卡片宽度(itemWidth)、隐藏底部指示器(pagination: null),再通过onIndexChanged监听选中状态即可。
  • carousel_slider:虽定位为轮播组件,但通过关闭无限滚动(enableInfiniteScroll: false)、调整视口占比(比如viewportFraction: 0.7让中间卡片突出显示),也能实现同款居中选中效果,配合onPageChanged处理选中逻辑。

二、自行实现方案(原生组件组合)

不想依赖第三方包的话,用ListView + PageController就能搞定,核心逻辑是利用PageController的滚动吸附特性实现居中选中:

完整代码示例

class LanguageSelector extends StatefulWidget {
  const LanguageSelector({super.key});

  @override
  State<LanguageSelector> createState() => _LanguageSelectorState();
}

class _LanguageSelectorState extends State<LanguageSelector> {
  final PageController _pageController = PageController(viewportFraction: 0.7);
  int _selectedIndex = 0;
  final List<String> _languages = ['English', 'Français', 'Español', 'Deutsch', '中文'];

  @override
  void initState() {
    super.initState();
    // 监听滚动,自动同步选中索引
    _pageController.addListener(() {
      final currentIndex = _pageController.page?.round() ?? 0;
      if (currentIndex != _selectedIndex) {
        setState(() => _selectedIndex = currentIndex);
      }
    });
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 100,
      child: ListView.builder(
        controller: _pageController,
        scrollDirection: Axis.horizontal,
        itemCount: _languages.length,
        padding: const EdgeInsets.symmetric(horizontal: 16),
        itemBuilder: (context, index) {
          final isSelected = index == _selectedIndex;
          return GestureDetector(
            onTap: () {
              setState(() => _selectedIndex = index);
              _pageController.animateToPage(
                index,
                duration: const Duration(milliseconds: 300),
                curve: Curves.ease,
              );
            },
            child: Container(
              width: MediaQuery.of(context).size.width * 0.7,
              margin: const EdgeInsets.symmetric(horizontal: 8),
              decoration: BoxDecoration(
                color: isSelected ? Colors.blueAccent : Colors.grey.shade200,
                borderRadius: BorderRadius.circular(12),
              ),
              child: Center(
                child: Text(
                  _languages[index],
                  style: TextStyle(
                    fontSize: 18,
                    fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
                    color: isSelected ? Colors.white : Colors.black87,
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

关键配置说明

  • PageController(viewportFraction: 0.7):设置每张卡片占屏幕宽度的70%,让左右能露出部分相邻卡片,还原图中视觉效果。
  • 点击卡片时调用animateToPage实现平滑滚动到目标项,提升交互体验。
  • 通过isSelected变量控制选中卡片的样式差异(背景色、文字粗细、颜色),明确选中状态。
  • 监听PageController的滚动事件,自动同步选中索引,实现滚动时的状态联动。

内容的提问来源于stack exchange,提问作者zied kanoun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:06:26