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

如何为Flutter中BottomNavigationBar的selectedItemColor添加渐变效果

给Flutter BottomNavigationBar的选中项添加渐变效果

原生的BottomNavigationBar的selectedItemColor属性不支持直接设置渐变效果,我们可以通过自定义选中状态下的图标和文字来实现这个需求。核心思路是用ShaderMask包裹图标和文本,为其添加渐变着色,然后根据当前选中的索引来切换显示普通样式还是渐变样式。

实现步骤与代码示例

  1. 封装带渐变的可复用组件
    先写一个通用组件,用来生成带渐变效果的图标和文字:

    class GradientIconText extends StatelessWidget {
      final IconData icon;
      final String label;
      final Gradient gradient;
    
      const GradientIconText({
        super.key,
        required this.icon,
        required this.label,
        required this.gradient,
      });
    
      @override
      Widget build(BuildContext context) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
            ShaderMask(
              shaderCallback: (bounds) => gradient.createShader(
                Rect.fromLTWH(0, 0, bounds.width, bounds.height),
              ),
              child: Icon(icon, color: Colors.white),
            ),
            const SizedBox(height: 4),
            ShaderMask(
              shaderCallback: (bounds) => gradient.createShader(
                Rect.fromLTWH(0, 0, bounds.width, bounds.height),
              ),
              child: Text(label, style: const TextStyle(color: Colors.white)),
            ),
          ],
        );
      }
    }
    
  2. 改造BottomNavigationBar实现
    维护当前选中索引,根据状态切换显示渐变组件或普通组件:

    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      int _selectedIndex = 0;
      // 自定义渐变样式,可按需修改颜色和方向
      final Gradient _selectedGradient = const LinearGradient(
        colors: [Colors.blue, Colors.purple],
        begin: Alignment.topLeft,
        end: Alignment.bottomRight,
      );
    
      void _onItemTapped(int index) {
        setState(() {
          _selectedIndex = index;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('渐变底部导航')),
          body: const Center(child: Text('首页内容')),
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: _selectedIndex,
            onTap: _onItemTapped,
            showUnselectedLabels: true,
            unselectedItemColor: Theme.of(context).colorScheme.onBackground,
            items: [
              BottomNavigationBarItem(
                icon: _selectedIndex == 0
                    ? GradientIconText(
                        icon: Icons.home,
                        label: 'Home',
                        gradient: _selectedGradient,
                      )
                    : const Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(Icons.home),
                          SizedBox(height: 4),
                          Text('Home'),
                        ],
                      ),
                label: '', // 自定义组件已包含文字,此处留空避免重复
              ),
              BottomNavigationBarItem(
                icon: _selectedIndex == 1
                    ? GradientIconText(
                        icon: Icons.favorite,
                        label: 'Favorite',
                        gradient: _selectedGradient,
                      )
                    : const Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(Icons.favorite),
                          SizedBox(height: 4),
                          Text('Favorite'),
                        ],
                      ),
                label: '',
              ),
              BottomNavigationBarItem(
                icon: _selectedIndex == 2
                    ? GradientIconText(
                        icon: Icons.settings,
                        label: 'Setting',
                        gradient: _selectedGradient,
                      )
                    : const Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(Icons.settings),
                          SizedBox(height: 4),
                          Text('Setting'),
                        ],
                      ),
                label: '',
              ),
              BottomNavigationBarItem(
                icon: _selectedIndex == 3
                    ? GradientIconText(
                        icon: Icons.abc,
                        label: 'idk',
                        gradient: _selectedGradient,
                      )
                    : const Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(Icons.abc),
                          SizedBox(height: 4),
                          Text('idk'),
                        ],
                      ),
                label: '',
              ),
            ],
          ),
        );
      }
    }
    

关键说明

  • ShaderMask是实现渐变着色的核心,它通过shaderCallback生成渐变着色器,将子组件的颜色替换为渐变效果。
  • 因为自定义组件已经包含了文字,所以BottomNavigationBarItem的label需要设为空字符串,避免重复显示文字。
  • 你可以直接修改_selectedGradient的颜色数组和对齐方式,快速切换不同的渐变风格。

内容的提问来源于stack exchange,提问作者Mohamad Bdeir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:21:09