一、列表页UI设计
二、关键技术
1.主要知识点
使用 Grid
组件创建网格布局,然后再使用 ForEach
遍历 numbers
数组,为每个数字创建 GridItem
。
numbers: string[]=['1','2','3','4','5','6','7','8','9','0','.']
Grid(){
ForEach(this.numbers,num=>{
GridItem(){
Text(num).fontSize(20).fontWeight(CommonConstants.FONT_WEIGHT_900)
}
.keyBoxStyle()
.onClick(()=> this.clickNumber(num))
})
GridItem(){
Text('删除').fontSize(20).fontWeight(CommonConstants.FONT_WEIGHT_900)
}
.keyBoxStyle()
.onClick(()=>this.clickDelete())
}
.width('100%')
.height(280)
.backgroundColor($r('app.color.index_page_background'))
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.padding(8)
.margin({top: 10})
clickNumber
函数处理数字按钮的点击事件,更新输入值和数量
clickNumber(num: string) {
// 1. 拼接用户输入的内容
// 当用户点击数字键时,将数字追加到当前的value字符串中
let val = this.value + num;
// 2. 校验输入格式是否正确
// 检查输入值中是否只包含一个'.',并且'.'不是在字符串的开头或结尾
// firstIndex 表示第一个'.'的位置
// lastIndex 表示最后一个'.'的位置
let firstIndex = val.indexOf('.');
let lastIndex = val.lastIndexOf('.');
if (firstIndex !== lastIndex || (lastIndex !== -1 && lastIndex < val.length - 2)) {
// 如果输入包含多于一个的'.',或者'.'在字符串的开头或紧邻结尾,则认为是非法输入
// 在这种情况下,不更新value,直接返回
return;
}
// 3. 将字符串转为数值
// 使用parseFloat方法将用户输入的字符串转换为浮点数
let amount = this.parseFloat(val);
// 4. 保存
// 检查转换后的数值是否大于或等于999.9
if (amount >= 999.9) {
// 如果数值大于或等于999.9,则将amount和value设置为999.9
this.amount = 999.9;
this.value = '999.9';
} else {
// 如果数值小于999.9,则将转换后的数值保存到amount,并将输入的字符串保存到value
this.amount = amount;
this.value = val;
}
}
clickDelete
函数处理删除操作,移除当前输入的最后一个字符
clickDelete() {
// 检查当前输入值value的长度
// 如果value为空字符串或者长度为0,表示没有内容可以删除
if (this.value.length <= 0) {
// 将value设置为空字符串,并将amount设置为0
this.value = '';
this.amount = 0;
// 无需进一步操作,直接返回
return;
}
// 如果value有内容,则执行删除操作
// 从当前value中删除最后一个字符
// substring方法从开始索引0处提取,直到但不包括指定的结束索引
this.value = this.value.substring(0, this.value.length - 1);
// 将更新后的字符串value转换为数值amount
// 调用parseFloat方法进行转换,确保数值格式正确
this.amount = this.parseFloat(this.value);
}
parseFloat
函数用于解析字符串为浮点数
parseFloat(str: string): number {
// 检查输入的字符串str是否为空、未定义或只有空白字符
if (!str) {
// 如果str为空,返回0作为默认值
return 0;
}
// 检查字符串str是否以点号'.'结尾
if (str.endsWith('.')) {
// 如果以点号结尾,去掉最后一个字符(即去掉多余的点号)
// 使用substring方法截取字符串,从索引0开始到但不包括索引str.length - 1
str = str.substring(0, str.length - 1);
}
// 使用全局的parseFloat函数将处理后的字符串转换为浮点数
// parseFloat函数解析字符串参数并返回一个浮点数
return parseFloat(str);
}
整体代码:
import colorSpaceManager from '@ohos.graphics.colorSpaceManager'
import { CommonConstants } from '../../common/constants/CommonConstants'
@Component
export default struct NumberKeyboard{
numbers: string[]=['1','2','3','4','5','6','7','8','9','0','.']
@Link amount :number
@Link value:string
@Styles keyBoxStyle(){
.backgroundColor(Color.White)
.borderRadius(8)
.height(60)
}
build(){
Grid(){
ForEach(this.numbers,num=>{
GridItem(){
Text(num).fontSize(20).fontWeight(CommonConstants.FONT_WEIGHT_900)
}
.keyBoxStyle()
.onClick(()=> this.clickNumber(num))
})
GridItem(){
Text('删除').fontSize(20).fontWeight(CommonConstants.FONT_WEIGHT_900)
}
.keyBoxStyle()
.onClick(()=>this.clickDelete())
}
.width('100%')
.height(280)
.backgroundColor($r('app.color.index_page_background'))
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)
.padding(8)
.margin({top: 10})
}
clickNumber(num :string ){
//1.拼接用户输入的内容
let val = this.value + num
//2.校验输入格式是否正确
let firstIndex = val.indexOf('.')
let lastIndex = val.lastIndexOf('.')
if (firstIndex!==lastIndex || (lastIndex !== -1 && lastIndex<val.length - 2)){
//非法输入
return
}
//3.将字符串转为数值
let amount = this.parseFloat(val)
//4.保存
if(amount>=999.9){
this.amount = 999.9
this.value='999.9'
}else{
this.amount=amount
this.value =val
}
}
clickDelete(){
if (this.value.length<=0){
this.value=''
this.amount =0
return
}
this.value = this.value.substring(0,this.value.length -1)
this.amount = this.parseFloat(this.value)
}
parseFloat(str:string){
if (!str){
return 0;
}
if (str.endsWith('.')){
str = str.substring (0, str.length -1)
}
return parseFloat(str)
}
}