当前位置: 首页 > news >正文

Flutter 自定义 Switch 切换组件完全指南

Flutter 自定义组件:Switch 切换实现

在 Flutter 中,你可以通过多种方式创建自定义的 Switch 切换组件。下面我将介绍几种实现方法,包括基础实现、自定义样式和完全自定义的 Switch 组件。

  1. 使用 Flutter 自带的 Switch 组件

最简单的方法是使用 Flutter 提供的 Switch 组件:

bool _switchValue = false;Switch(value: _switchValue,onChanged: (bool value) {setState(() {_switchValue = value;});},activeColor: Colors.blue, // 开启时的颜色activeTrackColor: Colors.blue[200], // 开启时轨道颜色inactiveThumbColor: Colors.grey, // 关闭时滑块颜色inactiveTrackColor: Colors.grey[300], // 关闭时轨道颜色
)
  1. 使用 CupertinoSwitch (iOS 风格)

如果你想要 iOS 风格的 Switch,可以使用 CupertinoSwitch:

bool _cupertinoSwitchValue = false;CupertinoSwitch(value: _cupertinoSwitchValue,onChanged: (bool value) {setState(() {_cupertinoSwitchValue = value;});},activeColor: Colors.blue,
)
  1. 完全自定义 Switch 组件

如果你想完全控制 Switch 的外观和行为,可以创建一个自定义组件:

自定义 Switch 实现

class CustomSwitch extends StatefulWidget {final bool value;final ValueChanged<bool> onChanged;final Color activeColor;final Color inactiveColor;final double width;final double height;const CustomSwitch({Key? key,required this.value,required this.onChanged,this.activeColor = Colors.blue,this.inactiveColor = Colors.grey,this.width = 50.0,this.height = 30.0,}) : super(key: key);_CustomSwitchState createState() => _CustomSwitchState();
}class _CustomSwitchState extends State<CustomSwitch> {Widget build(BuildContext context) {return GestureDetector(onTap: () {widget.onChanged(!widget.value);},child: AnimatedContainer(duration: const Duration(milliseconds: 200),width: widget.width,height: widget.height,decoration: BoxDecoration(borderRadius: BorderRadius.circular(widget.height),color: widget.value ? widget.activeColor : widget.inactiveColor,),child: Stack(children: [AnimatedPositioned(duration: const Duration(milliseconds: 200),left: widget.value ? widget.width - widget.height : 0,child: Container(width: widget.height,height: widget.height,decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.white,boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.2),blurRadius: 4,offset: const Offset(0, 2),),],),),),],),),);}
}

使用自定义 Switch

bool _customSwitchValue = false;CustomSwitch(value: _customSwitchValue,onChanged: (value) {setState(() {_customSwitchValue = value;});},activeColor: Colors.green,inactiveColor: Colors.red[200],width: 60,height: 35,
)
  1. 带图标和文本的自定义 Switch
class IconSwitch extends StatelessWidget {final bool value;final ValueChanged<bool> onChanged;final IconData activeIcon;final IconData inactiveIcon;final String activeText;final String inactiveText;final Color activeColor;final Color inactiveColor;const IconSwitch({Key? key,required this.value,required this.onChanged,this.activeIcon = Icons.check,this.inactiveIcon = Icons.close,this.activeText = 'ON',this.inactiveText = 'OFF',this.activeColor = Colors.green,this.inactiveColor = Colors.red,}) : super(key: key);Widget build(BuildContext context) {return GestureDetector(onTap: () => onChanged(!value),child: Container(padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),decoration: BoxDecoration(color: value ? activeColor : inactiveColor,borderRadius: BorderRadius.circular(20),),child: Row(mainAxisSize: MainAxisSize.min,children: [Icon(value ? activeIcon : inactiveIcon,color: Colors.white,size: 16,),const SizedBox(width: 4),Text(value ? activeText : inactiveText,style: const TextStyle(color: Colors.white,fontSize: 12,fontWeight: FontWeight.bold,),),],),),);}
}
  1. 动画增强版自定义 Switch
class AnimatedToggleSwitch extends StatefulWidget {final bool value;final ValueChanged<bool> onChanged;final Duration animationDuration;final Color activeColor;final Color inactiveColor;const AnimatedToggleSwitch({Key? key,required this.value,required this.onChanged,this.animationDuration = const Duration(milliseconds: 300),this.activeColor = Colors.blue,this.inactiveColor = Colors.grey,}) : super(key: key);_AnimatedToggleSwitchState createState() => _AnimatedToggleSwitchState();
}class _AnimatedToggleSwitchState extends State<AnimatedToggleSwitch>with SingleTickerProviderStateMixin {late AnimationController _controller;late Animation<double> _animation;void initState() {super.initState();_controller = AnimationController(vsync: this,duration: widget.animationDuration,);_animation = Tween<double>(begin: 0, end: 1).animate(_controller);if (widget.value) {_controller.value = 1.0;}}void didUpdateWidget(AnimatedToggleSwitch oldWidget) {super.didUpdateWidget(oldWidget);if (widget.value != oldWidget.value) {if (widget.value) {_controller.forward();} else {_controller.reverse();}}}void dispose() {_controller.dispose();super.dispose();}Widget build(BuildContext context) {return GestureDetector(onTap: () {widget.onChanged(!widget.value);},child: Container(width: 60,height: 30,decoration: BoxDecoration(borderRadius: BorderRadius.circular(15),color: Color.lerp(widget.inactiveColor,widget.activeColor,_animation.value,),),child: AnimatedBuilder(animation: _animation,builder: (context, child) {return Stack(children: [Positioned(left: _animation.value * 30,child: Container(width: 30,height: 30,decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.white,boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.2),blurRadius: 4,offset: const Offset(0, 2),),],),),),],);},),),);}
}

使用示例

class SwitchExamplePage extends StatefulWidget {const SwitchExamplePage({Key? key}) : super(key: key);_SwitchExamplePageState createState() => _SwitchExamplePageState();
}class _SwitchExamplePageState extends State<SwitchExamplePage> {bool _basicSwitch = false;bool _cupertinoSwitch = false;bool _customSwitch = false;bool _iconSwitch = false;bool _animatedSwitch = false;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Switch Examples')),body: Padding(padding: const EdgeInsets.all(16.0),child: Column(children: [ListTile(title: const Text('Basic Switch'),trailing: Switch(value: _basicSwitch,onChanged: (value) {setState(() {_basicSwitch = value;});},),),ListTile(title: const Text('Cupertino Switch'),trailing: CupertinoSwitch(value: _cupertinoSwitch,onChanged: (value) {setState(() {_cupertinoSwitch = value;});},),),ListTile(title: const Text('Custom Switch'),trailing: CustomSwitch(value: _customSwitch,onChanged: (value) {setState(() {_customSwitch = value;});},),),ListTile(title: const Text('Icon Switch'),trailing: IconSwitch(value: _iconSwitch,onChanged: (value) {setState(() {_iconSwitch = value;});},),),ListTile(title: const Text('Animated Switch'),trailing: AnimatedToggleSwitch(value: _animatedSwitch,onChanged: (value) {setState(() {_animatedSwitch = value;});},),),],),),);}
}

这些示例展示了从简单到复杂的各种 Switch 实现方式。你可以根据自己的需求选择合适的方法,或者在这些基础上进一步自定义。

http://www.xdnf.cn/news/1322461.html

相关文章:

  • 深度学习——R-CNN及其变体
  • React diff——差异协调算法简介
  • 【Python面试题】写一个用元类(metaclass)实现API接口自动注册的Demo。以及装饰器在项目中典型应用场景。
  • AI行业应用深度报告:金融、医疗、教育、制造业落地案例
  • 前端环境安装
  • AI 在金融领域的落地案例
  • go语言条件语if …else语句
  • ——链表——
  • 音频算法工程师技能1
  • 调试技巧(vs2022 C语言)
  • 【速通】深度学习模型调试系统化方法论:从问题定位到性能优化
  • 剧本杀小程序系统开发:保障游戏公平,营造健康娱乐环境
  • 蔬菜批发小程序:生产商的数字化转型利器——仙盟创梦IDE
  • 云计算-云上实例部署 RocketChat:Mongodb、主从数据库、Node 环境配置指南
  • 【人工智能】2025年AI代理失控危机:构建安全壁垒,守护智能未来
  • Python 面向对象三大特性详解(与 C++ 对比)
  • 【OpenAI】今日话题: GPT-4o-Audio-Preview 多模态语音交互模型介绍+API的使用教程!
  • 【verge3d】如何在项目里调用接口
  • ⭐CVPR2025 RigGS:从 2D 视频到可编辑 3D 关节物体的建模新范式
  • 【2025CVPR-目标检测方向】RaCFormer:通过基于查询的雷达-相机融合实现高质量的 3D 目标检测
  • BeeWorks 私有化会议系统:筑牢企业会议安全防线,赋能高效协同
  • 高并发网络编程实战:深入理解epoll客户端的事件驱动模型
  • OpenCV---特征检测算法(ORB,Oriented FAST and Rotated BRIEF)
  • css word-pass
  • 【LeetCode 热题 100】198. 打家劫舍——(解法二)自底向上
  • Linux磁盘阵列
  • ChatGPT-5 对教育行业的影响与案例研究
  • OpenAL技术详解:跨平台3D音频API的设计与实践
  • C++最小生成树
  • 手写MyBatis第24弹:从单条插入到批量处理:MyBatis性能优化的关键技术