鸿蒙NEXT开发案例:随机数生成

【引言】
本项目是一个简单的随机数生成器应用,用户可以通过设置随机数的范围和个数,并选择是否允许生成重复的随机数,来生成所需的随机数列表。生成的结果可以通过点击“复制”按钮复制到剪贴板。
【环境准备】
• 操作系统:Windows 10
• 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806
• 目标设备:华为Mate60 Pro
• 开发语言:ArkTS
• 框架:ArkUI
• API版本:API 12
【关键技术点】
1. 用户界面设计
用户界面主要包括以下几个部分:
• 标题栏:显示应用名称。
• 输入框:用户可以输入随机数的起始值、结束值和生成个数。
• 开关:用户可以选择生成的随机数是否允许重复。
• 生成按钮:点击后生成随机数。
• 结果显示区:显示生成的随机数,并提供复制功能。
2. 随机数生成算法
随机数生成是本项目的重点。根据用户是否允许生成重复的随机数,算法分为两种情况:
2.1 不允许重复
当用户选择不允许生成重复的随机数时,程序使用一个 Set 来存储生成的随机数,利用 Set 的特性自动去重。具体步骤如下:
1)计算范围:计算用户指定的随机数范围 range = endValue - startValue + 1。
2)生成随机数:使用一个临时数组 tempArray 来辅助生成不重复的随机数。每次生成一个随机索引 randomIndex,从 tempArray 中取出或计算一个新的随机数 randomNum,并将其添加到 Set 中。
3)更新临时数组:将 tempArray 中末尾的元素移动到随机位置,以确保下次生成的随机数仍然是唯一的。
if (!this.isUnique) {
if (countValue > range) {
// 显示错误提示
this.getUIContext().showAlertDialog({
title: '错误提示',
message: `请求的随机数数量超过了范围内的总数`,
confirm: {
defaultFocus: true,
value: '我知道了',
fontColor: Color.White,
backgroundColor: this.primaryColor,
action: () => {}
},
onWillDismiss: () => {},
alignment: DialogAlignment.Center,
});
return;
}
for (let i = 0; i < countValue; i++) {
let randomIndex = Math.floor(Math.random() * (range - i));
let randomNum = 0;
if (tempArray[randomIndex] !== undefined) {
randomNum = tempArray[randomIndex];
} else {
randomNum = startValue + randomIndex;
}
generatedNumbers.add(randomNum);
if (tempArray[range - 1 - i] === undefined) {
tempArray[range - 1 - i] = startValue + range - 1 - i;
}
tempArray[randomIndex] = tempArray[range - 1 - i];
}
this.generatedNumbers = JSON.stringify(Array.from(generatedNumbers));
}
3. 剪贴板功能
为了方便用户使用,程序提供了将生成的随机数复制到剪贴板的功能。具体实现如下:
private copyToClipboard(text: string): void {
const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text);
const systemPasteboard = pasteboard.getSystemPasteboard();
systemPasteboard.setData(pasteboardData);
promptAction.showToast({ message: '已复制' });
}
【完整代码】
// 导入剪贴板服务模块,用于后续实现复制功能
import { pasteboard } from '@kit.BasicServicesKit';
// 导入用于显示提示信息的服务
import { promptAction } from '@kit.ArkUI'; // 使用装饰器定义一个入口组件,这是应用的主界面
@Entry
@Component
struct RandomNumberGenerator {
// 定义基础间距,用于布局中的间距设置
@State private baseSpacing: number = 30;
// 存储生成的随机数字符串
@State private generatedNumbers: string = '';
// 应用的主题色
@State private primaryColor: string = '#fea024';
// 文本的颜色
@State private fontColor: string = "#2e2e2e";
// 输入框是否获取焦点的状态变量
@State private isFocusStart: boolean = false;
@State private isFocusEnd: boolean = false;
@State private isFocusCount: boolean = false;
// 是否允许生成的随机数重复
@State private isUnique: boolean = true;
// 随机数生成的起始值
@State private startValue: number = 0;
// 随机数生成的结束值
@State private endValue: number = 0;
// 要生成的随机数个数
@State private countValue: number = 0; // 生成随机数的方法
private generateRandomNumbers(): void {
const startValue = this.startValue; // 获取当前设定的起始值
const endValue = this.endValue; // 获取当前设定的结束值
const countValue = this.countValue; // 获取当前设定的生成个数
const range: number = endValue - startValue + 1; // 计算生成范围 // 用于存储生成的随机数
const generatedNumbers = new Set<number>(); // 使用Set来自动去重
const tempArray: number[] = []; // 临时数组,用于辅助生成不重复的随机数 // 如果不允许重复,则使用去重算法生成随机数
if (!this.isUnique) {
// 如果请求的随机数数量超过了范围内的总数,则显示错误提示
if (countValue > range) {
this.getUIContext().showAlertDialog({
title: '错误提示',
message: `请求的随机数数量超过了范围内的总数`,
confirm: {
defaultFocus: true,
value: '我知道了',
fontColor: Color.White,
backgroundColor: this.primaryColor,
action: () => {} // 点击确认后的回调
},
onWillDismiss: () => {}, // 对话框即将关闭时的回调
alignment: DialogAlignment.Center, // 对话框的对齐方式
});
return;
} for (let i = 0; i < countValue; i++) {
let randomIndex = Math.floor(Math.random() * (range - i)); // 在剩余范围内选择一个随机索引
let randomNum = 0;
if (tempArray[randomIndex] !== undefined) { // 如果索引位置已有值,则使用该值
randomNum = tempArray[randomIndex];
} else {
randomNum = startValue + randomIndex; // 否则计算新的随机数
}
generatedNumbers.add(randomNum); // 添加到Set中,自动去重
if (tempArray[range - 1 - i] === undefined) { // 更新末尾元素的位置
tempArray[range - 1 - i] = startValue + range - 1 - i;
}
tempArray[randomIndex] = tempArray[range - 1 - i]; // 将末尾元素移到随机位置
}
// 将生成的随机数转换成JSON格式的字符串
this.generatedNumbers = JSON.stringify(Array.from(generatedNumbers));
} else {
// 如果允许重复,则直接生成随机数
for (let i = 0; i < this.countValue; i++) {
let randomNumber = this.startValue + Math.floor(Math.random() * (this.endValue - this.startValue));
tempArray.push(randomNumber);
}
// 将生成的随机数转换成JSON格式的字符串
this.generatedNumbers = JSON.stringify(tempArray);
}
} // 将生成的随机数复制到剪贴板的方法
private copyToClipboard(text: string): void {
const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); // 创建剪贴板数据
const systemPasteboard = pasteboard.getSystemPasteboard(); // 获取系统剪贴板
systemPasteboard.setData(pasteboardData); // 设置剪贴板数据
// 显示复制成功的提示信息
promptAction.showToast({ message: '已复制' });
} // 构建页面布局的方法
build() {
Column() {
// 标题栏,展示应用名
Text("随机数生成")
.width('100%') // 设置宽度为100%
.height(54) // 设置高度为54
.fontSize(18) // 设置字体大小为18
.fontWeight(600) // 设置字体粗细为600
.backgroundColor(Color.White) // 设置背景颜色为白色
.textAlign(TextAlign.Center) // 设置文本居中对齐
.fontColor(this.fontColor); // 设置文本颜色 // 随机数范围设置区域
Column() {
Row() {
Text(`随机数范围`)
.fontWeight(600) // 设置字体粗细为600
.fontSize(18) // 设置字体大小为18
.fontColor(this.fontColor); // 设置文本颜色
}
.margin({ top: `${this.baseSpacing}lpx`, left: `${this.baseSpacing}lpx` }); // 设置边距 // 输入随机数范围的两个值
Row() {
TextInput({ placeholder: '开始(>=)' }) // 输入框,显示占位符
.layoutWeight(1) // 设置布局权重为1
.type(InputType.Number) // 设置输入类型为数字
.placeholderColor(this.isFocusStart ? this.primaryColor : Color.Gray) // 设置占位符颜色
.fontColor(this.isFocusStart ? this.primaryColor : this.fontColor) // 设置文本颜色
.borderColor(this.isFocusStart ? this.primaryColor : Color.Gray) // 设置边框颜色
.borderWidth(1) // 设置边框宽度
.borderRadius(10) // 设置圆角半径
.backgroundColor(Color.White) // 设置背景颜色
.showUnderline(false) // 不显示下划线
.onBlur(() => this.isFocusStart = false) // 输入框失去焦点时的处理
.onFocus(() => this.isFocusStart = true) // 输入框获得焦点时的处理
.onChange((value: string) => this.startValue = Number(value)); // 输入值变化时的处理 // 分隔符
Line().width(10) // 设置分隔符宽度 TextInput({ placeholder: '结束(<=)' }) // 输入框,显示占位符
.layoutWeight(1) // 设置布局权重为1
.type(InputType.Number) // 设置输入类型为数字
.placeholderColor(this.isFocusEnd ? this.primaryColor : Color.Gray) // 设置占位符颜色
.fontColor(this.isFocusEnd ? this.primaryColor : this.fontColor) // 设置文本颜色
.borderColor(this.isFocusEnd ? this.primaryColor : Color.Gray) // 设置边框颜色
.borderWidth(1) // 设置边框宽度
.borderRadius(10) // 设置圆角半径
.backgroundColor(Color.White) // 设置背景颜色
.showUnderline(false) // 不显示下划线
.onBlur(() => this.isFocusEnd = false) // 输入框失去焦点时的处理
.onFocus(() => this.isFocusEnd = true) // 输入框获得焦点时的处理
.onChange((value: string) => this.endValue = Number(value)); // 输入值变化时的处理
}
.margin({
left: `${this.baseSpacing}lpx`, // 左边距
right: `${this.baseSpacing}lpx`, // 右边距
top: `${this.baseSpacing}lpx`, // 上边距
}); // 输入生成随机数的个数
Text('生成随机数个数')
.fontWeight(600) // 设置字体粗细为600
.fontSize(18) // 设置字体大小为18
.fontColor(this.fontColor) // 设置文本颜色
.margin({ left: `${this.baseSpacing}lpx`, top: `${this.baseSpacing}lpx` }); // 设置边距 Row() {
TextInput({ placeholder: '' }) // 输入框,显示占位符
.layoutWeight(1) // 设置布局权重为1
.type(InputType.Number) // 设置输入类型为数字
.placeholderColor(this.isFocusCount ? this.primaryColor : Color.Gray) // 设置占位符颜色
.fontColor(this.isFocusCount ? this.primaryColor : this.fontColor) // 设置文本颜色
.borderColor(this.isFocusCount ? this.primaryColor : Color.Gray) // 设置边框颜色
.borderWidth(1) // 设置边框宽度
.borderRadius(10) // 设置圆角半径
.backgroundColor(Color.White) // 设置背景颜色
.showUnderline(false) // 不显示下划线
.onBlur(() => this.isFocusCount = false) // 输入框失去焦点时的处理
.onFocus(() => this.isFocusCount = true) // 输入框获得焦点时的处理
.onChange((value: string) => this.countValue = Number(value)); // 输入值变化时的处理
}
.margin({
left: `${this.baseSpacing}lpx`, // 左边距
right: `${this.baseSpacing}lpx`, // 右边距
top: `${this.baseSpacing}lpx`, // 上边距
}); // 设置数字是否可重复的开关
Row() {
Text('数字是否可重复')
.fontWeight(400) // 设置字体粗细为400
.fontSize(16) // 设置字体大小为16
.fontColor(this.fontColor) // 设置文本颜色
.layoutWeight(1); // 设置布局权重为1 Toggle({ type: ToggleType.Checkbox, isOn: this.isUnique }) // 切换按钮
.width('100lpx') // 设置宽度
.height('50lpx') // 设置高度
.borderColor(Color.Gray) // 设置边框颜色
.selectedColor(this.primaryColor) // 设置选中时的颜色
.onChange((isOn: boolean) => this.isUnique = isOn) // 切换状态变化时的处理
.align(Alignment.End); // 设置对齐方式为右对齐
}
.margin({
top: `${this.baseSpacing}lpx`, // 上边距
})
.width('100%') // 设置宽度为100%
.padding({
left: `${this.baseSpacing}lpx`, // 左内边距
right: `${this.baseSpacing}lpx`, // 右内边距
top: `${this.baseSpacing / 3}lpx`, // 上内边距
})
.hitTestBehavior(HitTestMode.Block) // 设置点击测试行为
.onClick(() => this.isUnique = !this.isUnique); // 点击时切换状态 // 生成随机数的按钮
Text('开始生成')
.fontColor(Color.White) // 设置文本颜色为白色
.backgroundColor(this.primaryColor) // 设置背景颜色为主题色
.height(54) // 设置高度为54
.textAlign(TextAlign.Center) // 设置文本居中对齐
.borderRadius(10) // 设置圆角半径
.fontSize(18) // 设置字体大小为18
.width(`${650 - this.baseSpacing * 2}lpx`) // 设置宽度
.margin({
top: `${this.baseSpacing}lpx`, // 上边距
left: `${this.baseSpacing}lpx`, // 左边距
right: `${this.baseSpacing}lpx`, // 右边距
bottom: `${this.baseSpacing}lpx` // 下边距
})
.clickEffect({ level: ClickEffectLevel.HEAVY, scale: 0.8 }) // 设置点击效果
.onClick(() => this.generateRandomNumbers()); // 点击时生成随机数
}
.width('650lpx') // 设置宽度
.margin({ top: 20 }) // 设置上边距
.backgroundColor(Color.White) // 设置背景颜色为白色
.borderRadius(10) // 设置圆角半径
.alignItems(HorizontalAlign.Start); // 设置水平对齐方式为左对齐 // 显示生成的随机数
Column() {
Text(`生成的随机数为:`)
.fontWeight(600) // 设置字体粗细为600
.fontSize(18) // 设置字体大小为18
.fontColor(this.fontColor) // 设置文本颜色
.margin({
top: `${this.baseSpacing}lpx`, // 上边距
left: `${this.baseSpacing}lpx`, // 左边距
}); Text(`${this.generatedNumbers}`) // 显示生成的随机数
.width('650lpx') // 设置宽度
.fontColor(this.primaryColor) // 设置文本颜色为主题色
.fontSize(18) // 设置字体大小为18
.textAlign(TextAlign.Center) // 设置文本居中对齐
.padding({ left: 5, right: 5 }) // 设置内边距
.margin({
top: `${this.baseSpacing / 3}lpx` // 上边距
}); // 复制生成的随机数到剪贴板的按钮
Text('复制')
.enabled(this.generatedNumbers ? true : false) // 按钮是否可用
.fontColor(Color.White) // 设置文本颜色为白色
.backgroundColor(this.primaryColor) // 设置背景颜色为主题色
.height(54) // 设置高度为54
.textAlign(TextAlign.Center) // 设置文本居中对齐
.borderRadius(10) // 设置圆角半径
.fontSize(18) // 设置字体大小为18
.width(`${650 - this.baseSpacing * 2}lpx`) // 设置宽度
.margin({
top: `${this.baseSpacing}lpx`, // 上边距
left: `${this.baseSpacing}lpx`, // 左边距
right: `${this.baseSpacing}lpx`, // 右边距
bottom: `${this.baseSpacing}lpx` // 下边距
})
.clickEffect({ level: ClickEffectLevel.HEAVY, scale: 0.8 }) // 设置点击效果
.onClick(() => this.copyToClipboard(this.generatedNumbers)); // 点击时复制随机数
}
.width('650lpx') // 设置宽度
.backgroundColor(Color.White) // 设置背景颜色为白色
.borderRadius(10) // 设置圆角半径
.margin({ top: `${this.baseSpacing}lpx` }) // 设置上边距
.alignItems(HorizontalAlign.Start); // 设置水平对齐方式为左对齐
}
.height('100%') // 设置高度为100%
.width('100%') // 设置宽度为100%
.backgroundColor("#f2f3f5"); // 设置背景颜色
}
}
鸿蒙NEXT开发案例:随机数生成的更多相关文章
- 最全华为鸿蒙 HarmonyOS 开发资料汇总
开发 本示例基于 OpenHarmony 下的 JavaScript UI 框架,进行项目目录解读,JS FA.常用和自定义组件.用户交互.JS 动画的实现,通过本示例可以基本了解和学习到 JavaS ...
- 使用Jquery+EasyUI 进行框架项目开发案例讲解之五 模块(菜单)管理源码分享
http://www.cnblogs.com/huyong/p/3454012.html 使用Jquery+EasyUI 进行框架项目开发案例讲解之五 模块(菜单)管理源码分享 在上四篇文章 ...
- 使用Jquery+EasyUI 进行框架项目开发案例讲解之四 组织机构管理源码分享
http://www.cnblogs.com/huyong/p/3404647.html 在上三篇文章 <使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享> ...
- 使用Jquery+EasyUI 进行框架项目开发案例讲解之三---角色管理源码分享
使用Jquery+EasyUI 进行框架项目开发案例讲解之三 角色管理源码分享 在上两篇文章 <使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享> ...
- 使用Jquery+EasyUI 进行框架项目开发案例讲解之二---用户管理源码分享
使用Jquery+EasyUI 进行框架项目开发案例讲解之二 用户管理源码分享 在上一篇文章<使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享>我们分享 ...
- 【推荐】使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享
使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工管理源码分享 在开始讲解之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery的U ...
- 使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享
使用Jquery+EasyUI 进行框架项目开发案例解说之中的一个 员工管理源代码分享 在開始解说之前,我们先来看一下什么是Jquery EasyUI?jQuery EasyUI是一组基于jQuery ...
- 百度UEditor开发案例(JSP)
本案例的开发环境:MyEclipse+tomcat+jdk 本案例的开发内容: 用百度编辑器发布新闻(UEditor的初始化开发部署) 编辑已发过的新闻(UEditor的应用——编辑旧文章) ...
- 使用Jquery+EasyUI 进行框架项目开发案例解说之二---用户管理源代码分享
使用Jquery+EasyUI 进行框架项目开发案例解说之二 用户管理源代码分享 在上一篇文章<使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享> ...
- 使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享
使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享 使用Jquery+EasyUI 进行框架项目开发案例讲解之一 员工管理源码分享 在开始讲解之前,我们先来看一下什 ...
随机推荐
- IDEA maven 项目 如何获取项目离线运行所需的全部依赖( .m2格式)
背景:maven项目要将整个项目的依赖移植到某无法联网服务器进行测试,需要项目离线运行所需的全部依赖 步骤: 1. 首先需要有项目源码,解压后,使用IDEA Open Project 2. 在Sett ...
- RabbitMQ核心概念以及工作原理【转】
RabbitMQ核心概念以及工作原理 我们来看看流行的RabbitMQ消息系统以及它是如何让你的系统之间进行解耦的. 英文原文 RabbitMQ 在这篇短文里,我们会介绍什么是RabbitMQ,它 ...
- AWS 认证
Data Analytics: 准备先Fundamental, 然后Udemy 上买课程,在看Exam Readiness, 然后小测试一下水平,看白皮书,最后不行就 Guru上再买课程 https: ...
- jstack排查cpu占用高的步骤
通过jstack排查cpu占用高的问题 1.通过top命令找到cpu占用高的应用程序进程 2.通过top -H -p pid查看该应用中占用CPU高的线程. 3.通过printf "%x\n ...
- error: rpmdb: BDB0113... rpm安装或尝查询时报错
等保要求安装杀毒软件,我跑脚本的时候发现异常退出了,一查芜湖,rpm管理包出问题了 root@VM_0_12_centos equal-protection]# rpm -g clamav error ...
- kubernetes重新初始化“[ERROR DirAvailable--var-lib-etcd]”
[root@master01 ~]# kubeadm init --config /root/kubeadm-config.yaml --upload-certs [init] Using Kuber ...
- opencv colors
""" 在利用python进行画图时,我们可能常常用的颜色就是'k'黑色,'r'红色,'b'蓝色,'g'绿色等,这些颜色分别代表常见的 几种颜色.但是当我们画图比较多时, ...
- Angular 18+ 高级教程 – HttpClient
前言 HttpClient 是 Angular 对 XMLHttpRequest 和 Fetch 的封装. HttpClient 的 DX (Developer Experience) 比 XMLHt ...
- 前端基本功——面试必问系列(1):都2024了,还没吃透Promise?一文搞懂
写在前面: 大家好,我是山里看瓜,该系列文章是为了帮助大家不管面试还是开发对前端的一些基本但是很重要的知识点认识更加深入和全面. 想写这个系列文章的初衷是:我发现前端的很多基本知识,使用起来很简单,定 ...
- 选择:Qt Creator、Qt Designer、Qt Design Studio,三种开发工具,您选择哪一种?
前言 本文介绍了三种QT开发工具的特点,以及各自的优点和缺点. QT三种工具对比 QT提供的工具 Qt Creator: 扮演的是QT Widgets和QT QML的IDE的角色. 优点: 可以编写C ...