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

Flutter---音效模式选择器

效果图

主要功能:

音效模式切换:用户可以在三种音效模式之间循环切换

  • 🎵 音乐模式 - 背景:音乐背景图,图标:苹果

  • 🎬 电影模式 - 背景:电影背景图,图标:香蕉

  • 🎮 游戏模式 - 背景:游戏背景图,图标:樱桃

交互功能:

左右切换:

  • 点击左侧图标(芒果)切换到上一个模式

  • 点击右侧图标(芒果)切换到下一个模式

  • 支持循环切换(音乐 ↔ 电影 ↔ 游戏)

页面布局:

  • 顶部:返回按钮(樱桃图标) + 模式标题

  • 中部:模式描述文字

  • 底部:模式选择控件 + 确认按钮(三色渐变)

步骤

①新建枚举

enum SoundMode{music,movie,game}

②新建私有变量,设置为当前选中模式,默认为音乐模式

//当前选中的模式SoundMode _currentMode = SoundMode.music;//进入的第一个页面

③通过switch/case获取当前的背景图、中间的图标、当前模式的标题、模式的描述、

  //获取当前模式的背景图String get _backgroundImage{switch(_currentMode){case SoundMode.music:return "assets/images/music_mode_background.jpg";case SoundMode.movie:return "assets/images/movie_mode_background.jpg";case SoundMode.game:return "assets/images/game_mode_background.jpg";default:return "assets/images/music_mode_background.jpg";}}//获取当前模式的中间图标String get _centerIcon{switch(_currentMode){case SoundMode.music:return "assets/images/apple.png";case SoundMode.movie:return "assets/images/banana.png";case SoundMode.game:return "assets/images/cherry.png";}}//获取当前模式的标题String get _modeTitle{switch(_currentMode){case SoundMode.music:return "音乐模式";case SoundMode.movie:return "电影模式";case SoundMode.game:return "游戏模式";}}//获取当前模式的描述List<String> get _modeDescription{switch(_currentMode){case SoundMode.music:return ["这是音乐模式","音乐模式很好"];case SoundMode.movie:return ["这是电影模式","电影模式很好"];case SoundMode.game:return ["这是游戏模式","游戏模式很好"];}}

④写左右按钮切换模式的点击事件

  //切换到上一个模式void _previousMode(){setState(() {final index = SoundMode.values.indexOf(_currentMode); //获取当前模式下标_currentMode = SoundMode.values[(index - 1) % SoundMode.values.length];});}//切换到下一个模式void _nextMode(){setState(() {final index = SoundMode.values.indexOf(_currentMode);//获取当前模式下标_currentMode = SoundMode.values[(index + 1) % SoundMode.values.length];//假设当前index = 0,则(0+1)%3 = 1,则SoundMode.values[1] = movie,然后重新构建UI});}

点击事件的实现

//下一个模式
_nextMode() 执行过程:
1. index = SoundMode.values.indexOf(_currentMode) → index = 0 (因为_currentMode是music)2. (index + 1) % SoundMode.values.length→ (0 + 1) % 3 = 1 % 3 = 13. SoundMode.values[1] → SoundMode.movie4. _currentMode = SoundMode.movie//上一个模式_previousMode() 执行过程(假设当前是movie):
1. index = SoundMode.values.indexOf(_currentMode) → index = 1 (因为_currentMode是movie)2. (index - 1) % SoundMode.values.length→ (1 - 1) % 3 = 0 % 3 = 03. SoundMode.values[0] → SoundMode.music4. _currentMode = SoundMode.music

完整的触发流程

用户点击 → 调用 _nextMode()/_previousMode() → setState() → 重建UI↓
_currentMode 改变 → 所有getter重新计算↓
_backgroundImage → 返回新背景图路径
_centerIcon → 返回新图标路径  
_modeTitle → 返回新标题
_modeDescription → 返回新描述↓
UI使用新值重新渲染 → 用户看到界面更新

⑤建造UI,使用Stack,叠加布局

body: Stack(children: [Container(height: double.infinity,width: double.infinity,decoration: BoxDecoration(image: DecorationImage(image: AssetImage(_backgroundImage), //动态背景图片fit:BoxFit.cover,),),child: Column(mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.center,children: [Padding(padding: EdgeInsets.only(top:50,left:27),child: Row(mainAxisAlignment: MainAxisAlignment.start,children: [Image.asset("assets/images/cherry.png",width: 20,height: 20,),const SizedBox(width: 102,),Text(_modeTitle,style: const TextStyle(color: Colors.white,fontSize: 22,fontWeight: FontWeight.bold),),],),),const SizedBox(height: 350,),//动态描述for (var description in _modeDescription)Text(description,style: const TextStyle(color: Colors.black,fontSize: 14,),),const SizedBox(height: 67,),Row(mainAxisAlignment: MainAxisAlignment.center,children: [GestureDetector(onTap: _previousMode,child: Image.asset("assets/images/mango.png",width: 20,height: 20,),),const SizedBox(width: 21,),Container(width: 1,height: 48,decoration: const BoxDecoration(color: Color(0xFFD8D8D8),),),const SizedBox(width: 45,),Image.asset(_centerIcon,width: 35,height: 35,),const SizedBox(width: 45,),Container(width: 1,height: 48,decoration: const BoxDecoration(color: Color(0xFFD8D8D8),),),const SizedBox(width: 21,),GestureDetector(onTap: _nextMode,child: Image.asset("assets/images/mango.png",width: 20,height: 20,),),],),//确认按钮const SizedBox(height: 50,),Container(width: 249,height: 48,decoration: BoxDecoration(borderRadius: BorderRadius.circular(27),gradient: const LinearGradient(begin: Alignment.centerLeft,    // 从上开始end: Alignment.centerRight,   // 到底结束colors: [Colors.blue,      // 顶部颜色Colors.blueGrey,     // 中间颜色Colors.green,    // 底部颜色],),),child: Center(child: Text("确认",style: const TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 24,),),),),],),),],),

⑥UI中有一个三种颜色的渲染按钮(从左到右),改变两个参数就能变成从上到下的渲染

//确认按钮const SizedBox(height: 50,),Container(width: 249,height: 48,decoration: BoxDecoration(borderRadius: BorderRadius.circular(27),gradient: const LinearGradient(begin: Alignment.centerLeft,    // 左到右end: Alignment.centerRight,   //从上到下渲染,可以换成topCenter到bottomCentercolors: [Colors.blue,      // 顶部颜色Colors.blueGrey,     // 中间颜色Colors.green,    // 底部颜色],),),child: Center(child: Text("确认",style: const TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 24,),),),),

代码实例


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';enum SoundMode{music,movie,game}class HomePage extends StatefulWidget{const HomePage({super.key});@overrideState<StatefulWidget> createState() => _HomePageState();}class _HomePageState extends State<HomePage> {//当前选中的模式SoundMode _currentMode = SoundMode.music;//进入的第一个页面//获取当前模式的背景图String get _backgroundImage{switch(_currentMode){case SoundMode.music:return "assets/images/music_mode_background.jpg";case SoundMode.movie:return "assets/images/movie_mode_background.jpg";case SoundMode.game:return "assets/images/game_mode_background.jpg";default:return "assets/images/music_mode_background.jpg";}}//获取当前模式的中间图标String get _centerIcon{switch(_currentMode){case SoundMode.music:return "assets/images/apple.png";case SoundMode.movie:return "assets/images/banana.png";case SoundMode.game:return "assets/images/cherry.png";}}//获取当前模式的标题String get _modeTitle{switch(_currentMode){case SoundMode.music:return "音乐模式";case SoundMode.movie:return "电影模式";case SoundMode.game:return "游戏模式";}}//获取当前模式的描述List<String> get _modeDescription{switch(_currentMode){case SoundMode.music:return ["这是音乐模式","音乐模式很好"];case SoundMode.movie:return ["这是电影模式","电影模式很好"];case SoundMode.game:return ["这是游戏模式","游戏模式很好"];}}//切换到上一个模式void _previousMode(){setState(() {final index = SoundMode.values.indexOf(_currentMode); //获取当前模式下标_currentMode = SoundMode.values[(index - 1) % SoundMode.values.length];});}//切换到下一个模式void _nextMode(){setState(() {final index = SoundMode.values.indexOf(_currentMode);//获取当前模式下标_currentMode = SoundMode.values[(index + 1) % SoundMode.values.length];//假设当前index = 0,则(0+1)%3 = 1,则SoundMode.values[1] = movie,然后重新构建UI});}//UI构建@overrideWidget build(BuildContext context) {return Scaffold(body: Stack(children: [Container(height: double.infinity,width: double.infinity,decoration: BoxDecoration(image: DecorationImage(image: AssetImage(_backgroundImage), //动态背景图片fit:BoxFit.cover,),),child: Column(mainAxisAlignment: MainAxisAlignment.start,crossAxisAlignment: CrossAxisAlignment.center,children: [Padding(padding: EdgeInsets.only(top:50,left:27),child: Row(mainAxisAlignment: MainAxisAlignment.start,children: [Image.asset("assets/images/cherry.png",width: 20,height: 20,),const SizedBox(width: 102,),Text(_modeTitle,style: const TextStyle(color: Colors.white,fontSize: 22,fontWeight: FontWeight.bold),),],),),const SizedBox(height: 350,),//动态描述for (var description in _modeDescription)Text(description,style: const TextStyle(color: Colors.black,fontSize: 14,),),const SizedBox(height: 67,),Row(mainAxisAlignment: MainAxisAlignment.center,children: [GestureDetector(onTap: _previousMode,child: Image.asset("assets/images/mango.png",width: 20,height: 20,),),const SizedBox(width: 21,),Container(width: 1,height: 48,decoration: const BoxDecoration(color: Color(0xFFD8D8D8),),),const SizedBox(width: 45,),Image.asset(_centerIcon,width: 35,height: 35,),const SizedBox(width: 45,),Container(width: 1,height: 48,decoration: const BoxDecoration(color: Color(0xFFD8D8D8),),),const SizedBox(width: 21,),GestureDetector(onTap: _nextMode,child: Image.asset("assets/images/mango.png",width: 20,height: 20,),),],),//确认按钮const SizedBox(height: 50,),Container(width: 249,height: 48,decoration: BoxDecoration(borderRadius: BorderRadius.circular(27),gradient: const LinearGradient(begin: Alignment.centerLeft,    // 左到右end: Alignment.centerRight,   //从上到下渲染,可以换成topCenter到bottomCentercolors: [Colors.blue,      // 顶部颜色Colors.blueGrey,     // 中间颜色Colors.green,    // 底部颜色],),),child: Center(child: Text("确认",style: const TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 24,),),),),],),),],),);}
}

http://www.dtcms.com/a/499546.html

相关文章:

  • 信号量 semaphore 机制可实现基于条件变量 condition variable 的管程 monitor 机制
  • 市工商局网站建设情况网页截图快捷键ctrl加什么
  • C++数据类型
  • FFmpeg 核心 API 系列:音频重采样 SwrContext 完全指南(新API版本)
  • 网站建设数据收集方法南昌网站推广¥做下拉去118cr
  • visio画网站开发类图深圳东道建设集团网站
  • 董付国老师Python小屋编程题答案161-170
  • 国外营销企业网站什么叫高端网站定制
  • Flutter---生命周期
  • 百度网址大全网站互联网家装
  • 专业的东莞网站排名WordPress多站点开启多语言
  • 微信端网站开发流程做网站什么配置够用
  • c# 泛型的详细介绍
  • OceanBase的SQL和执行计划监控视图
  • 网站原创内容优化wordpress 网站内跳转
  • 龙口市规划建设局网站南京app开发公司排名
  • 解决 Hugging Face 国内下载慢的问题:用 ModelScope 替代加速模型获取
  • 从基础到深入:自然语言处理核心技术全梳理(有 ML/DL 基础)
  • 合肥建设公司网站wordpress 个人电脑
  • 做网站需要哪些方面的支出新媒体运营需要学什么
  • 云手机群控是什么意思
  • 【ecfw】ecfw构建基础
  • 常州二建建设有限公司官方网站聊城做wap网站哪儿好
  • php做网站需要html国外设计公司名字
  • CUDA nvjpeg库编码jpeg图像
  • AI 工作流实战 - 调用豆包api实现批量生图
  • 如何编写您的第一个 Linux 设备驱动程序(一)
  • 做更好的自己 网站客户又找不到你
  • Spring MVC 封装全局统一异常处理
  • 海尔建设网站的内容wordpress设置教程