如何在ThemeData中为Bottom Navigation Bar设置Linear Gradient选中图标
核心实现逻辑是用ShaderMask组件给图标做渐变着色,Flutter原生Icon不支持直接设置渐变,这是目前最稳定、无额外依赖的实现方式。
具体实现步骤
- 不要给选中态图标手动设置固定色值,否则会覆盖渐变效果。
- 给BottomNavigationBarItem的
activeIcon属性传入经ShaderMask包裹的图标组件,着色模式指定为BlendMode.srcIn,保证渐变只填充图标本身的形状,不会溢出到周边区域。 - 按需配置LinearGradient的渐变方向、色值组、停留占比即可。
可直接运行的代码示例
import 'package:flutter/material.dart'; class GradientNavPage extends StatefulWidget { const GradientNavPage({super.key}); @override State<GradientNavPage> createState() => _GradientNavPageState(); } class _GradientNavPageState extends State<GradientNavPage> { int _selectedIndex = 0; // 封装通用渐变图标组件 Widget gradientIcon(IconData iconData, {double size = 24}) { return ShaderMask( blendMode: BlendMode.srcIn, shaderCallback: (Rect iconBounds) { return const LinearGradient( // 渐变方向可自行调整,示例为左上到右下 begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Color(0xFF2196F3), Color(0xFF9C27B0), ], ).createShader(iconBounds); }, child: Icon(iconData, size: size), ); } @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: BottomNavigationBar( currentIndex: _selectedIndex, unselectedItemColor: Colors.grey.shade400, onTap: (index) => setState(() => _selectedIndex = index), items: [ BottomNavigationBarItem( icon: const Icon(Icons.home_outlined), // 选中态传入渐变图标 activeIcon: gradientIcon(Icons.home), label: '首页', ), BottomNavigationBarItem( icon: const Icon(Icons.category_outlined), activeIcon: gradientIcon(Icons.category), label: '分类', ), BottomNavigationBarItem( icon: const Icon(Icons.shopping_cart_outlined), activeIcon: gradientIcon(Icons.shopping_cart), label: '购物车', ), BottomNavigationBarItem( icon: const Icon(Icons.person_outline), activeIcon: gradientIcon(Icons.person), label: '我的', ), ], ), ); } }
注意事项
- 如果使用自定义图片图标、SVG图标,只需要把
ShaderMask里的Icon替换成对应图标组件即可,实现逻辑完全一致。 - 如果需要全局统一样式,可以直接在BottomNavigationBar的
selectedIconTheme中配置,不用逐个给item设置activeIcon。 - 若需要给图标加渐变描边、发光等效果,可以在渐变配置里多叠加一层半透明色值实现。
内容的提问来源于stack exchange,提问作者Melvin
相关产品推荐
相关产品推荐

