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

Flutter for OpenHarmony 实战_随机抽签应用设计与实现

Flutter for OpenHarmony 实战:随机抽签应用设计与实现

欢迎加入开源鸿蒙跨平台社区:开源鸿蒙跨平台开发者社区

文章目录

  • Flutter for OpenHarmony 实战:随机抽签应用设计与实现
    • 前言
    • 一、抽签算法实现
      • 1.1 基础随机选择
      • 1.2 多次抽签
      • 1.3 权重抽签
    • 二、候选人管理
      • 2.1 添加候选人
      • 2.2 批量导入
      • 2.3 删除候选人
    • 三、抽签动画
      • 3.1 滚动动画
      • 3.2 结果对话框
    • 四、UI界面设计
      • 4.1 主界面布局
      • 4.2 候选人列表
      • 4.3 控制按钮
    • 五、历史记录
      • 5.1 记录存储
      • 5.2 历史显示
    • 六、设置功能
      • 6.1 动画时长
      • 6.2 音效开关
    • 七、数据持久化
      • 7.1 保存数据
      • 7.2 加载数据
    • 总结

前言

随机抽签应用是一个实用的工具类应用,广泛应用于抽奖、分组、决策等场景。本文将详细介绍随机抽签算法、候选人管理、动画效果实现、结果历史记录以及UI交互设计。

一、抽签算法实现

1.1 基础随机选择

classLotterySystem{List<String>candidates=[];StringdrawWinner(){if(candidates.isEmpty){return'';}finalrandom=Random();finalindex=random.nextInt(candidates.length);returncandidates[index];}}

使用Random().nextInt()生成随机索引,从候选人列表中选择一个。

1.2 多次抽签

List<String>drawMultiple(int count){if(count>candidates.length){throwException('抽签数量超过候选人数量');}finalselected=<String>[];finalavailable=List<String>.from(candidates);for(int i=0;i<count;i++){finalrandom=Random();finalindex=random.nextInt(available.length);selected.add(available[index]);available.removeAt(index);}returnselected;}

支持一次抽取多个不重复的候选人。

1.3 权重抽签

classWeightedCandidate{finalStringname;finalint weight;WeightedCandidate({requiredthis.name,requiredthis.weight});}StringdrawWeighted(List<WeightedCandidate>candidates){finaltotalWeight=candidates.fold(0,(sum,c)=>sum+c.weight);finalrandom=Random();finalrandomValue=random.nextInt(totalWeight);int currentWeight=0;for(varcandidateincandidates){currentWeight+=candidate.weight;if(randomValue<currentWeight){returncandidate.name;}}returncandidates.last.name;}

根据权重进行抽签,权重越高被抽中的概率越大。

二、候选人管理

2.1 添加候选人


voidaddCandidate(Stringname){if(name.trim().isEmpty){return;}if(candidates.contains(name)){ScaffoldMessenger.of(context).showSnackBar(constSnackBar(content:Text('该候选人已存在')),);return;}setState((){candidates.add(name);});}

添加候选人时检查重复和空名称。

2.2 批量导入

voidimportCandidates(Stringtext){finallines=text.split('\n');int added=0;for(varlineinlines){finalname=line.trim();if(name.isNotEmpty&&!candidates.contains(name)){candidates.add(name);added++;}}ScaffoldMessenger.of(context).showSnackBar(SnackBar(content:Text('成功导入$added个候选人')),);}

支持从文本批量导入候选人,每行一个。

2.3 删除候选人

voidremoveCandidate(Stringname){setState((){candidates.remove(name);});}voidclearAll(){showDialog(context:context,builder:(context)=>AlertDialog(title:constText('清空候选人'),content:constText('确定要清空所有候选人吗?'),actions:[TextButton(onPressed:()=>Navigator.pop(context),child:constText('取消'),),TextButton(onPressed:(){setState((){candidates.clear();});Navigator.pop(context);},child:constText('确定'),),],),);}

提供单个删除和清空全部功能。

三、抽签动画

3.1 滚动动画

StringcurrentDisplay='';bool isAnimating=false;List<String>history=[];voidstartDrawing()async{if(candidates.isEmpty||isAnimating){return;}isAnimating=true;finalduration=constDuration(milliseconds:2000);finalstart=DateTime.now();while(DateTime.now().difference(start)<duration){finalrandom=Random();currentDisplay=candidates[random.nextInt(candidates.length)];setState((){});awaitFuture.delayed(constDuration(milliseconds:50));}// 最终结果finalwinner=drawWinner();currentDisplay=winner;history.add(winner);isAnimating=false;setState((){});showResultDialog(winner);}

2秒内快速滚动显示候选人名称,制造悬念。

3.2 结果对话框

voidshowResultDialog(Stringwinner){showDialog(context:context,builder:(context)=>AlertDialog(title:constText('抽签结果'),content:Column(mainAxisSize:MainAxisSize.min,children:[constIcon(Icons.celebration,size:64,color:Colors.amber),constSizedBox(height:16),Text(winner,style:constTextStyle(fontSize:32,fontWeight:FontWeight.bold),),],),actions:[TextButton(onPressed:()=>Navigator.pop(context),child:constText('确定'),),],),);}

使用对话框展示最终结果,带有庆祝图标。

四、UI界面设计

4.1 主界面布局

@overrideWidgetbuild(BuildContextcontext){returnScaffold(appBar:AppBar(title:constText('随机抽签'),actions:[IconButton(icon:constIcon(Icons.history),onPressed:showHistory),IconButton(icon:constIcon(Icons.settings),onPressed:showSettings),],),body:Column(children:[Expanded(child:Center(child:Text(currentDisplay,style:Theme.of(context).textTheme.displayLarge,),),),_buildCandidateList(),_buildControlButtons(),],),);}

中心显示当前抽签结果,下方是候选人列表和控制按钮。

4.2 候选人列表

Widget_buildCandidateList(){returnContainer(height:200,padding:constEdgeInsets.all(16),child:ListView.builder(itemCount:candidates.length,itemBuilder:(context,index){returnListTile(title:Text(candidates[index]),trailing:IconButton(icon:constIcon(Icons.remove_circle),onPressed:()=>removeCandidate(candidates[index]),),);},),);}

可滚动的候选人列表,每个项带删除按钮。

4.3 控制按钮

Widget_buildControlButtons(){returnPadding(padding:constEdgeInsets.all(16),child:Row(mainAxisAlignment:MainAxisAlignment.spaceEvenly,children:[ElevatedButton.icon(onPressed:isAnimating?null:startDrawing,icon:constIcon(Icons.play_arrow),label:constText('开始抽签'),),ElevatedButton.icon(onPressed:()=>addCandidateDialog(),icon:constIcon(Icons.add),label:constText('添加候选人'),),],),);}

开始抽签和添加候选人两个主要按钮。

五、历史记录

5.1 记录存储

List<String>history=[];List<DateTime>timestamps=[];voidaddToHistory(Stringwinner){history.add(winner);timestamps.add(DateTime.now());}

记录抽签结果和时间戳。

5.2 历史显示

voidshowHistory(){showDialog(context:context,builder:(context)=>AlertDialog(title:constText('抽签历史'),content:SizedBox(width:double.maxFinite,height:400,child:ListView.builder(itemCount:history.length,itemBuilder:(context,index){finalreversedIndex=history.length-1-index;returnListTile(title:Text(history[reversedIndex]),subtitle:Text(_formatTime(timestamps[reversedIndex])),leading:Text('${reversedIndex+1}'),);},),),actions:[TextButton(onPressed:()=>Navigator.pop(context),child:constText('关闭'),),TextButton(onPressed:(){setState((){history.clear();timestamps.clear();});Navigator.pop(context);},child:constText('清空历史'),),],),);}

显示所有历史记录,最新记录在前。

六、设置功能

6.1 动画时长

int animationDuration=2000;// 毫秒voidupdateDuration(int duration){setState((){animationDuration=duration;});}

允许用户调整抽签动画时长。

6.2 音效开关

bool soundEnabled=true;voidtoggleSound(){setState((){soundEnabled=!soundEnabled;});}

控制抽签时是否播放音效。

七、数据持久化

7.1 保存数据

Future<void>saveData()async{finalprefs=awaitSharedPreferences.getInstance();awaitprefs.setStringList('candidates',candidates);awaitprefs.setStringList('history',history);}

使用SharedPreferences保存候选人和历史记录。

7.2 加载数据

Future<void>loadData()async{finalprefs=awaitSharedPreferences.getInstance();finalsavedCandidates=prefs.getStringList('candidates');finalsavedHistory=prefs.getStringList('history');if(savedCandidates!=null){setState((){candidates=savedCandidates;});}if(savedHistory!=null){history=savedHistory;}}

应用启动时自动加载数据。

总结

本文详细介绍了随机抽签应用的设计与实现。从随机算法到候选人管理,从动画效果到UI设计,每个技术点都直接影响应用的功能性和用户体验。通过这些技术的综合应用,实现了功能完整且实用的随机抽签应用。

http://www.jsqmd.com/news/362701/

相关文章:

  • Stable Diffusion WebUI + cpolar,让 AI 绘画自由不设限
  • 禁忌搜索算法的全貌与应用解析
  • Flutter for OpenHarmony 实战_消消乐游戏策略设计与难度平衡
  • linux自启动和开机直接显示html页面
  • uemetahuman 插件学习笔记
  • Flutter for OpenHarmony 实战_飞翔的小鸟游戏物理引擎与管道生成
  • Pr自动字幕识别插件哪个好?千鹿Pr助手支持SRT导出+智能断句,每日免费!
  • MySQL 进阶篇: 锁机制深度解析
  • Pr怎么给视频添加字幕?2种方法对比,第2种效率提升10倍!
  • 深入解析:LTE FDD与TDD融合技术介绍
  • 大数据领域分布式计算的磁盘计算优化
  • 2026年隔声材料厂家推荐:丙烯酸复合橡胶弹性隔声涂层哪家好/丙烯酸聚合物水泥弹性隔声涂层/选择指南 - 优质品牌商家
  • 编写社交礼仪助手,根据社交场景(聚餐/面试/约会/婚礼),推荐合适的社交礼仪,穿搭建议,话术,避免社交难堪,提升社交能力,适合年轻人。
  • 2026年超纯水器行业全景报告:技术演进、市场格局与供应商战略深度解析 - 品牌推荐大师
  • 让机器学会“听诊”:基于集成学习的心肺听诊音自动分类系统设计与实现
  • 两种方式构造数独
  • 编写节日祝福助手,根据不同节日(春节/中秋/情人节/圣诞节),祝福对象,(家人/朋友/领导/客户),自动生成节日祝福短信/微信模板,支持自定义修改,一键发送。
  • 20260209--《构建之法》读后感--其一
  • 当2026的实习生说“接受无薪”时,近屿智能看到了什么?
  • 2026年出口固定式破碎锤厂家权威推荐榜:破碎生产线固定式机械臂、隔筛固定式机械臂、隔筛固定式破碎锤选择指南 - 优质品牌商家
  • 2026年纹眉培训学校厂家推荐:仪器野生眉纹绣培训学校/半永久纹眉/发际线培训学校/妈生感纹眉/小班纹眉培训/选择指南 - 优质品牌商家
  • 2026年假山建造厂家权威推荐榜:溶洞假山设计、假山设计、卡通民宿设计、护坡假山设计施工、景区民宿修建选择指南 - 优质品牌商家
  • 2026.2.9
  • nvm,node,npm关系
  • 浅析二叉树、B树、B+树、B*树和MySQL索引底层原理
  • 2026年企业加密软件评测服务推荐,数据防泄露系统平台助你提升安全防护 - 睿易优选
  • @RefreshScope和Environment
  • 历史_
  • 惊爆!提示工程架构师揭秘Agentic AI技术生态与未来走向
  • 防雷接地材料厂家推荐 适配多行业核心需求 - 优质品牌商家