HarmonyOS第三章:初识ArkTs/ArkUI,常用组件二

🎉 博客主页:【剑九 六千里-CSDN博客
🎨 上一篇文章:【HarmonyOS学习第二章:初识ArkTs/ArkUI,常用组件一
🎠 系列专栏:【轻松学会HarmonyOS开发
💖 感谢大家点赞👍收藏⭐评论✍

在这里插入图片描述

在这里插入图片描述
引言
本文档详细介绍了在鸿蒙应用开发中使用@ohos.promptAction模块提供的几种弹窗功能,以及全局UI弹窗的使用方法,并探讨了组件状态管理事件处理机制。以下是对各部分内容的总结:

  1. @ohos.promptAction 弹窗功能
  • 提示弹窗 showToast():用于显示简短的消息提示,可自定义消息内容、显示时长及距离屏幕底部的位置。
  • 对话弹窗 showDialog():提供带标题和自定义按钮的对话框,支持监听用户点击按钮的响应。
  • 菜单弹窗 showActionMenu():展示带有多个选项的菜单,用户选择后可触发相应的回调。
  1. 全局UI弹窗
  • 警告弹窗 AlertDialog.show():灵活配置标题、内容、按钮样式及行为,支持自动关闭、位置对齐等特性。
  • 列表选择弹窗 ActionSheet.show():以列表形式展示选项供用户选择,每个选项均可绑定点击回调。
  • 日期选择弹窗 DatePickerDialog.show():支持公历和农历的选择,可设定日期范围和初始选中日期。
  • 时间选择弹窗 TimePickerDialog.show():提供12小时和24小时两种时间格式选择。
  • 文本滑动选择器弹窗 TextPickerDialog.show():适用于从预设字符串列表中选择一项的场景。
  1. 组件状态 @State
  • 作用:@State装饰器用于声明组件的状态变量,确保状态改变时能自动更新UI。
  • 对比:未使用@State的变量更改不会触发UI重绘,而装饰过的状态变量会自动同步到视图。
  1. 组件事件
  • 示例:通过登录功能展示了如何绑定输入框的onChange事件来更新状态,并利用按钮的onClick事件处理登录逻辑。
  • 最佳实践:建议将复杂的逻辑处理代码抽象到单独的方法中,以保持UI构建代码的清晰和逻辑的可维护性。
  • 注意事项:推荐使用箭头函数处理事件,避免this上下文问题,并注意鸿蒙Next版本对函数表达式的限制。

1. @ohos.promptAction (弹窗)

1.1. 提示弹窗-showToast()

在这里插入图片描述

import promptAction from '@ohos.promptAction'
@Entry
@Component
struct madel {
  build() {
    Column() {
      Button('打开弹窗')
        .onClick(() => {
          promptAction.showToast(({
            message: '请联系管理员',
            duration: 3000,
            bottom: 500
          }))
        })
    }.width('100%').height('100%')
  }
}

参数说明:

名称类型必填说明
messagestring显示的文本信息。默认字体为’Harmony Sans’,不支持设置其他字体。
durationnumber默认值1500ms,取值区间:1500ms-10000ms。若小于1500ms则取默认值,若大于10000ms则取上限值10000ms。
bottomstring或number设置弹窗边框距离屏幕底部的位置。

1.2. 对话弹窗-showDialog()

示例:

在这里插入图片描述
参考代码:

import promptAction from '@ohos.promptAction'
@Entry
@Component
struct ConfirmMadel {
  build() {
    Column() {
      Button('打开弹窗')
        .onClick(() => {
          promptAction.showDialog({
            title: '确认要删除吗?',
            message: '请点击确定后删除',
            buttons: [
              {
                text: '取消',
                color: '#000000',
              },
              {
                text: '确定',
                color: 'red',
              }
            ],
          },(err, data) => {
            if (err) {
              console.info('取消删除', err);
              return;
            }
            console.info('删除成功', data.index);
          })
        })
    }
    .width('100%')
    .height('100%')
  }
}

输出结果如下:
在这里插入图片描述
参数说明:

名称类型必填说明
titlestring标题文本。
messagestring内容文本。
buttons[Button,Button?,Button?]对话框中按钮的数组,结构为:{text:‘button’, color: ‘#666666’},支持1-3个按钮。其中第一个为positiveButton;第二个为negativeButton;第三个为neutralButton。

1.3. 菜单弹窗-showActionMenu()

示例:
在这里插入图片描述
参考代码:

import promptAction from '@ohos.promptAction'
@Entry
@Component
struct MadelMenu {
  build() {
    Column() {
      Button('打开弹窗')
        .onClick(() => {
          promptAction.showActionMenu({
            title: '请选择',
            buttons: [
              {
                text: '香蕉',
                color: '#666666'
              },
              {
                text: '苹果',
                color: '#666666'
              },
            ]
          },(err, data) => {
            if (err) {
              console.info('取消了~', err);
              return;
            }
            console.info('选中了~', data.index)
          })
        })
    }
    .width('100%')
    .height('100%')
  }
}
}

输出结果:
在这里插入图片描述
参数说明:

名称类型必填说明
titlestring标题文本。
buttons[Button,Button?,Button?,Button?,Button?,Button?]菜单中菜单项按钮的数组,结构为:{text:‘button’, color: ‘#666666’},支持1-6个按钮。大于6个按钮时弹窗不显示。

2. 全局UI弹窗

2.1. 警告弹窗

示例:
在这里插入图片描述

参考代码:

@Entry
@Component
struct DialogAlert {
  build() {
    Column({ space: 5 }) {
      Button('警告弹窗')
        .onClick(() => {
          AlertDialog.show({
            title: '警告', // 弹窗标题
            message: '确定删除吗?', // 弹窗内容
            autoCancel: true, // 点击遮罩层时,弹窗是否关闭
            alignment: DialogAlignment.Bottom, // 设置弹窗位置
            offset: { dx: 0, dy: -20 }, // 弹窗相对alignment所在位置的偏移量
            gridCount: 3, // 弹窗容器宽度所占用栅格数

            // 单个按钮
            // confirm: {
            //   value: '确定',
            //   action: () => {
            //     console.info('Button-clicking callback')
            //   }
            // },

            // 多个按钮
            primaryButton: {
              value: '取消', // 按钮内容
              fontColor: Color.Blue, // 按钮文字颜色
              backgroundColor: Color.Orange, // 按钮背景颜色
              action: () => { // 回调
                console.info('Callback when the first button is clicked')
              }
            },
            secondaryButton: {
              value: '确定',
              fontColor: Color.Red,
              backgroundColor: Color.Orange,
              action: () => {
                console.info('Callback when the second button is clicked')
              }
            },

            cancel: () => {
              console.info('Closed callbacks')
            }
          })
        }).backgroundColor(Color.Red)
    }
    .width('100%')
    .height('100%')
  }
}

输出结果:
在这里插入图片描述

AlertDialog.show() 参数说明:

参数名参数类型必填参数描述
titlestring弹窗标题。
messagestring弹窗内容。
autoCancelboolean点击遮障层时,是否关闭弹窗。默认值:true
confirm{value: ResourceStr,fontColor?: ResourceColor,backgroundColor?: ResourceColor,action: () => void}确认按钮的文本内容、文本色、按钮背景色和点击回调。
cancel() => void点击遮障层关闭dialog时的回调。
alignmentDialogAlignment 枚举弹窗在竖直方向上的对齐方式。默认值:DialogAlignment.Default
offset弹窗相对alignment所在位置的偏移量。
gridCountnumber弹窗容器宽度所占用栅格数。

DialogAlignment 枚举值说明:

属性描述
Top垂直顶部对齐。
Bottom垂直底部对齐。
Center垂直居中对齐。
Default默认对齐。
TopStart左上对齐。
TopEnd右上对齐。
CenterStart左中对齐。
CenterEnd右中对齐。
BottomStart左下对齐。
BottomEnd右下对齐。

2.2. 列表选择弹窗

示例:
在这里插入图片描述

参考代码:

@Entry
@Component
struct DialogList {
  build() {
    Column(){
      Button("列表选择弹窗").onClick(()=>{
        ActionSheet.show({
          title: '请选择水果', // 弹窗标题
          message: '水果信息', // 弹窗信息
          autoCancel: true, // 点击遮罩层,是否关闭弹窗
          confirm: {
            value: '确认按钮',
            action: () => {
              console.log('确认点击成功')
            }
          },
          cancel: () => {
            console.log('你点击了关闭')
          },
          alignment: DialogAlignment.Bottom, // 弹窗位置
          offset: { dx: 0, dy: -20 }, // 弹窗相对alignment所在位置的偏
          sheets: [ // 列表项
            {
              title: 'apples', // 列表每一项的名称
              action: () => { // 选中后的回调
                console.log('apples')
              }
            },
            {
              title: 'bananas',
              action: () => {
                console.log('bananas')
              }
            },
            {
              title: 'pears',
              action: () => {
                console.log('pears')
              }
            }
          ]
        })
      })
    }
    .width("100%")
    .height("100%")
  }
}

2.3. 日期滑动选择器弹窗

示例-公历:
在这里插入图片描述
示例-农历:
在这里插入图片描述
参考代码:

@Entry
@Component
struct DialogDate {
  selectedDate: Date = new Date("2024-6-1")
  build() {
    Column(){
      Button("阳历日期")
        .margin(20)
        .onClick(() => {
          DatePickerDialog.show({
            start: new Date("2000-1-1"),
            end: new Date("2100-12-31"),
            selected: this.selectedDate,
            onAccept: (value: DatePickerResult) => {
              // 通过Date的setFullYear方法设置按下确定按钮时的日期,这样当弹窗再次弹出时显示选中的是上一次确定的日期
              this.selectedDate.setFullYear(value.year, value.month, value.day)
              console.info("DatePickerDialog:onAccept()" + JSON.stringify(value))
            },
            onCancel: () => {
              console.info("DatePickerDialog:onCancel()")
            },
            onChange: (value: DatePickerResult) => {
              console.info("DatePickerDialog:onChange()" + JSON.stringify(value))
            }
          })
        })

      Button("Lunar 阴历日期")
        .margin(20)
        .onClick(() => {
          DatePickerDialog.show({
            start: new Date("2000-1-1"),
            end: new Date("2100-12-31"),
            selected: this.selectedDate,
            lunar: true,
            onAccept: (value: DatePickerResult) => {
              this.selectedDate.setFullYear(value.year, value.month, value.day)
              console.info("DatePickerDialog:onAccept()" + JSON.stringify(value))
            },
            onCancel: () => {
              console.info("DatePickerDialog:onCancel()")
            },
            onChange: (value: DatePickerResult) => {
              console.info("DatePickerDialog:onChange()" + JSON.stringify(value))
            }
          })
        })
    }
    .width("100%")
    .height("100%")
  }
}

2.4. 时间滑动选择器弹窗

示例-12小时制:
在这里插入图片描述
示例-24小时制:
在这里插入图片描述
参考代码:

@Entry
@Component
struct DialogTime {
  private selectTime: Date = new Date('2020-12-25T08:30:00')
  build() {
    Column(){
      Button("TimePickerDialog 12小时制")
        .margin(20)
        .onClick(() => {
          TimePickerDialog.show({
            selected: this.selectTime,
            onAccept: (value: TimePickerResult) => {
              // 设置selectTime为按下确定按钮时的时间,这样当弹窗再次弹出时显示选中的为上一次确定的时间
              this.selectTime.setHours(value.hour, value.minute)
              console.info("TimePickerDialog:onAccept()" + JSON.stringify(value))
            },
            onCancel: () => {
              console.info("TimePickerDialog:onCancel()")
            },
            onChange: (value: TimePickerResult) => {
              console.info("TimePickerDialog:onChange()" + JSON.stringify(value))
            }
          })
        })
      Button("TimePickerDialog 24小时制")
        .margin(20)
        .onClick(() => {
          TimePickerDialog.show({
            selected: this.selectTime,
            useMilitaryTime: true,
            onAccept: (value: TimePickerResult) => {
              this.selectTime.setHours(value.hour, value.minute)
              console.info("TimePickerDialog:onAccept()" + JSON.stringify(value))
            },
            onCancel: () => {
              console.info("TimePickerDialog:onCancel()")
            },
            onChange: (value: TimePickerResult) => {
              console.info("TimePickerDialog:onChange()" + JSON.stringify(value))
            }
          })
        })
    }
    .width("100%")
    .height("100%")
  }
}

2.5. 文本滑动选择器弹窗

示例:
在这里插入图片描述
参考代码:

@Entry
@Component
struct DialogText {
  @State select: number  = 2
  private fruits: string[] = ['橘子', '香蕉', '苹果', '西瓜', '榴莲']

  build() {
    Row() {
      Column() {
        Button("文本滑动选择器")
          .margin(20)
          .onClick(() => {
            TextPickerDialog.show({
              range: this.fruits,
              selected: this.select,
              onAccept: (value: TextPickerResult) => {
                // 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项
                this.select = value.index as number;
                console.info("TextPickerDialog:onAccept()" + JSON.stringify(value))
              },
              onCancel: () => {
                console.info("TextPickerDialog:onCancel()")
              },
              onChange: (value: TextPickerResult) => {
                console.info("TextPickerDialog:onChange()" + JSON.stringify(value))
              }
            })
          })
      }.width('100%')
    }.height('100%')
  }
}

输出:
在这里插入图片描述

3. 组件状态 @State

3.1. @state是什么?

@State 是一种用于定义状态变量的装饰器;简单理解就是定义响应式变量;

1)普通组件变量,不具有UI更新能力(不具备响应式)。

数据更新,视图并未更新:
在这里插入图片描述

@Entry
@Component
struct StatePage {
  count: number = 0;
  build() {
    Column(){
      Text(`${this.count}`)
        .fontSize(30)

      Button("增加").onClick(()=>{
        this.count++;
        console.info(`${this.count}`)
      })
    }
    .width("100%")
    .height("100%")
  }
}

2)数据变量驱动UI更新,必须加上@state装饰器,并明确指定其数据类型和初始值:
在这里插入图片描述

@Entry
@Component
struct StatePage {
  @State count: number = 0;
  build() {
    Column(){
      Text(`${this.count}`)
        .fontSize(30)

      Button("增加").onClick(()=>{
        this.count++;
        console.info(`${this.count}`)
      })
    }
    .width("100%")
    .height("100%")
  }
}

4. 组件事件

模拟一个用户登录的功能:
1)基础结构:
在这里插入图片描述
参考代码:

@Entry
@Component
struct EventPage {
  build() {
    Column() {
      TextInput({placeholder: '请输入账号'})
        .margin({ bottom: 10 })
        .height(45)
        .backgroundColor(Color.Pink)
      TextInput({placeholder: '请输入密码'})
        .type(InputType.Password)
        .margin({ bottom: 10 })
        .height(45)
        .backgroundColor(Color.Pink)
      Button('登录')
    }.width('100%').height('100%')
  }
}

2)增加数据绑定、change事件及click事件:

在这里插入图片描述
参考代码:

@Entry
@Component
struct EventPage {
  @State username: string = '';
  @State password: string = '';
  build() {
    Column() {
      TextInput({placeholder: '请输入账号'})
        .margin({ bottom: 10 })
        .height(45)
        .backgroundColor(Color.Pink)
        .onChange((value) => {
          this.username = value;
        })
      TextInput({placeholder: '请输入密码'})
        .type(InputType.Password)
        .margin({ bottom: 10 })
        .height(45)
        .backgroundColor(Color.Pink)
        .onChange((value) => {
          this.password = value;
        })
      Button('登录')
        .enabled(this.username !== "" && this.password !== "") // 输入值为空则返回false,阻止执行,否则返回true
        .onClick(() => {
          if(this.username === 'admin' && this.password === 'admin123') {
            AlertDialog.show({
              message: '登录成功'
            })
          } else {
            AlertDialog.show({
              message: '账号或密码错误'
            })
          }
        })
    }.width('100%').height('100%')
  }
}

3)这样写功能可以实现,但代码并不够清晰,因此可以将一些方法抽取出来,这样做有助于保持UI代码的简洁性和可读性,同时将逻辑处理与界面展示分离:

@Entry
@Component
struct EventPage {
  @State username: string = '';
  @State password: string = '';

  validate() {
    return this.username !== "" && this.password !== ""
  }
  login() {
    if(this.username === 'admin' && this.password === 'admin123') {
      AlertDialog.show({
        message: '登录成功'
      })
    } else {
      AlertDialog.show({
        message: '账号或密码错误'
      })
    }
  }
  build() {
    Column() {
      TextInput({ placeholder: '请输入账号' })
        .margin({ bottom: 10 })
        .height(45)
        .backgroundColor(Color.Pink)
        .onChange((value) => {
          this.username = value;
        })
      TextInput({ placeholder: '请输入密码' })
        .type(InputType.Password)
        .margin({ bottom: 10 })
        .height(45)
        .backgroundColor(Color.Pink)
        .onChange((value) => {
          this.password = value;
        })
      Button('登录')
        .enabled(this.validate()) // 输入值为空则返回false,阻止执行,否则返回true
        .onClick(() => {
          this.login()
        })
    }.width('100%').height('100%')
  }
}

注意:注册事件时请使用箭头函数·() => {}·,因为这样不会涉及this指向问题;同时在鸿蒙next版本之后已经不支持function() {}这种写法了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剑九_六千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>