当前位置: 首页 > 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.dtcms.com/a/337255.html

相关文章:

  • 技术经典场景之协议转换
  • IR-CUT与CCD CMOS的关系
  • 国标:开展环境卫生满意度调查
  • 【P18 3-10】OpenCV Python—— 鼠标控制,鼠标回调函数(鼠标移动、按下、。。。),鼠标绘制基本图形(直线、圆、矩形)
  • 【笔记】和各大AI大语言模型合作写项目—slirp.go
  • 之前说的要写的TCP高性能服务器,今天来了
  • 算法题打卡力扣第26. 删除有序数组中的重复项(easy))
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段蓝宝书,共120语法(4):31-40语法
  • 在react props中在参数中定义参数类型
  • Leetcode 16 java
  • 发布npmjs组件库
  • 政策技术双轮驱动智慧灯杆市场扩容,塔能科技破解行业痛点
  • 使用AWS S3 + Lambda + MediaConvert 实现上传视频文件并自动转码
  • 像素风球球大作战 HTML 游戏
  • 隐秘参数APP:全面了解手机硬件信息与优化性能
  • 从零开始搭建React+TypeScript+webpack开发环境——多环境配置管理方案
  • WMS仓库管理系统如何远程访问?
  • RAID服务器
  • qsort函数使用及其模拟实现
  • 视觉语言导航(2)——VLN RNN TRANSFORMER 与ATTENTION 2.2+LSTM(单独一节)
  • 分治-归并-493.翻转对-力扣(LeetCode)
  • 艺术品与收藏直播驱动数字化鉴赏与交易
  • 设计模式笔记_行为型_访问者模式
  • 双通道审核智能合约更新路径:基于区块链与AI融合的编程范式分析
  • MATLAB建模与可视化技术文档:从二维到三维
  • snprintf
  • 《Python学习之使用标准库:从入门到实战》
  • 104、【OS】【Nuttx】【周边】文档构建渲染:安装 Sphinx 扩展(上)
  • 从零到一构建企业级GraphRAG系统:GraphRag.Net深度技术解析
  • Python Ovito统计多晶晶粒数量