import { it } from '@ohos/hypium'; import { IBestToast, YTAvoid, YTButton, YTHeader } from 'basic' import { LengthMetrics, promptAction } from '@kit.ArkUI'; @Builder function RanNumberViewBuilder(){ NavDestination(){ RanNumberView() }.title("随机数") .hideTitleBar(true) } @Component struct RanNumberView{ @StorageProp(YTAvoid.SAFE_TOP_KEY) safeBottom: number = 0 // 存储生成的随机数字符串 @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; @State private randomNumberArr:number[]=[] /** * todo:bug: * 改变值,会引起UI刷新 */ // 生成随机数的方法 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(); // 使用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); } //最终将生成的字符串转化为数组 this.randomNumberArr=JSON.parse(this.generatedNumbers) // this.flexChangeValue=this.countValue } // // 将生成的随机数复制到剪贴板的方法 // 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() { YTHeader({ title: '随机数' }) //声音 Row(){ Image($r('app.media.app_icon')).width(24) }.width('100%') .justifyContent(FlexAlign.Start) .padding({left:30}) Column() { Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.SpaceBetween }) { ForEach(this.randomNumberArr, (item: number, index: number) => { Column() { Text(item.toString()).width(30) } .width(this.countValue > 3 ? 70 : 95) .height(this.countValue > 3 ? 60 : 85) .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .margin({ bottom: 20 }) .backgroundImage($r('[basic].media.number')) .backgroundImageSize({ width: "100%", height: '100%' }) }) }.padding({ left: 30, right: 30 }) }.width('100%') .height(300) // 输入随机数范围的两个值 Column({space:20}) { Row() { Text('取值范围:').margin({right:30}) TextInput() // 输入框,显示占位符 .width(60) .height(60) .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) => { if(Number(value)>100){ IBestToast.show({ message:'生成范围只能是100以内' }) return } if(Number(value)<=0){ IBestToast.show({ message:'生成范围只能是100以内' }) return } this.startValue = Number(value) }); // 输入值变化时的处理 // 分隔符 // Line().width(10) // 设置分隔符宽度 Text().width(30).height(1).fontColor(Color.Gray) TextInput() // 输入框,显示占位符 .width(60) .height(60) .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) =>{ if(Number(value)>100){ IBestToast.show({ message:'生成范围只能是100以内' }) return } if(Number(value)<=0){ IBestToast.show({ message:'生成范围只能是100以内' }) return } this.endValue = Number(value) }); // 输入值变化时的处理 }.width('100%').margin({top:10}) Row() { Text('生成个数:').margin({right:30}) TextInput({ placeholder: ''}) // 输入框,显示占位符 .width(60) .height(60) .type(InputType.Number) // 设置输入类型为数字 .placeholderColor(this.isFocusCount ? this.primaryColor : Color.Gray) // 设置占位符颜色 .fontColor(this.isFocusCount ? this.primaryColor : this.fontColor) // 设置文本颜色 .borderColor(Color.Orange) // 设置边框颜色 .borderWidth(1) // 设置边框宽度 .borderRadius(10) // 设置圆角半径 .backgroundColor(Color.White) // 设置背景颜色 .showUnderline(false) // 不显示下划线 .onBlur(() => this.isFocusCount = false) // 输入框失去焦点时的处理 .onFocus(() => this.isFocusCount = true) // 输入框获得焦点时的处理 .onChange((value: string) =>{ if(Number(value)>10){ IBestToast.show({ message:'只能生成10个数' }) return } if(Number(value)<0){ IBestToast.show({ message:'不能是负数' }) return } this.countValue = Number(value) }); // 输入值变化时的处理 }.width('100%') }.width(330) .height(170) .padding({left:30,top:10}) .borderRadius(20) .backgroundColor('#e0f8ff') .justifyContent(FlexAlign.Start) Text('生成范围为100以内,最多生成10个数') Button('数字是否可以重复').onClick(()=>{ this.isUnique=!this.isUnique }) Text(JSON.stringify(this.isUnique)) YTButton({ bgc:'#fd54e3', btHeight:54, btBorderRadius:20, btWidth:300, btFontColor:Color.White, btFontSize:20, click:()=>{ this.generateRandomNumbers() }, btContent:'随机数生成' }) }.padding({ bottom: this.safeBottom }) .height('100%') .backgroundColor(Color.White) .backgroundImage($r('[basic].media.backimgNumber')) .backgroundImageSize({width:'100%',height:"100%"}) } } /** * 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); // 点击时切换状态 */