【鸿蒙(HarmonyOS)】Router(路由)、CustomDialog(弹窗)、Popup(气泡提示)和setTimeout(定时服务)的使用(以登录模块为例)

一、引言

  • 描述:如何在鸿蒙系统中开发一个功能齐全的登录模块,具备准确的定位提示。
  • 难度:初级
  • 知识点:
  • 1、Router页面路由
  • 2、CustomDialog自定义弹窗
  • 3、Popup气泡提示
  • 4、setTimeout定时器
  • 效果:
  • 在这里插入图片描述

二、设计

1、UI设计

(1)主布局

关于布局构建,可以参考同栏目中的文章,以下是大致的布局,后面再完善

在这里插入图片描述

@Entry
@Component
struct Index {

  @State name: string = ""
  @State pass: string = ""
  @State btnLogin: string = "登录"

  build() {
    Row() {
      Column() {
        // person
        Image($r('app.media.person')).width(100).height(100).margin({top:80, bottom:50})
        // data
        TextArea({ placeholder : "账号/电话号码"})
          .margin(15)
          .onChange((value: string) => {
          	// TOD 数据绑定
            this.name = value
          })
        TextInput({ placeholder : "密码", text : this.pass})
          .margin(15)
          .type(InputType.Password)
          .onChange((value: string) => {
          	// TOD 数据绑定
            this.pass = value
          })
        // btn
        Button(this.btnLogin, { type: ButtonType.Normal, stateEffect: true })
          .borderRadius(18)
          .backgroundColor(0x317aff)
          .width(90)
          .height(40)
          .margin({top:50})
          .onClick(() => {
          	// TODO 登录逻辑
            ...
          })
      }
    }
  }
}

(2)CustomDialog

CustomDialog(弹窗):可用于广告、中奖、警告、软件更新等与用户交互响应操作。

  • 第一步:@CustomDialog装饰器用于装饰自定义弹框,此装饰器内进行自定义内容。
// 弹出登录成功的信息
@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController
  build() {
    Column() {
      Text('登录成功')
        .fontSize(20)
        .margin({ top: 10, bottom: 10 })
        .borderRadius(5)
    }
  }
}
  • 第二步:@CustomDialog装饰器用于装饰自定义弹框,此装饰器内进行自定义内容。
@Entry
@Component
struct Index {

	// 创建构造器
	dialogController: CustomDialogController = new CustomDialogController({
  		builder: CustomDialogExample({}),
	})

	...

}
  • 第三步:点击与onClick事件绑定的组件使弹窗弹出。
@Entry
@Component
struct Index {

	...

	build() {
    Row() {
      Column() {
      	  Flex({justifyContent:FlexAlign.Center}) {
          Button(this.btnLogin, { type: ButtonType.Normal, stateEffect: true })
            .borderRadius(18)
            .backgroundColor(0x317aff)
            .width(90)
            .height(40)
            .margin({ top: 50 })
            .onClick(() => {
                // 打开自定义弹窗
                this.dialogController.open()
                // 定时关闭弹窗(1s)
                setTimeout(() => {
                  // 关闭自定义弹窗
                  this.dialogController.close()
                }, 1000)
            })
        }
      }
     }
    }

}

(3)Popup

Popup(气泡提示):可绑定在组件上显示气泡弹窗提示,设置弹窗内容、交互逻辑和显示状态。

  • 以当个输入框为例

在这里插入图片描述

@Entry
@Component
struct Index {

  @State name: string = ""
  @State pass: string = ""
  @State btnLogin: string = "登录"
  @State handlePopup_name: boolean = false
  @State handlePopup_pass: boolean = false
  @State handlePopup_btn: boolean = false

  // TODO 创建构造器

  build() {
    Row() {
      Column() {
        // person
        ...
        // data
        ...
        TextInput({ placeholder : "密码", text : this.pass})
          .margin(15)
          .type(InputType.Password)
          .onChange((value: string) => {
            ...
          })
          .bindPopup(this.handlePopup_pass, {
            message: '密码为空',
          })
        // btn
        Flex({justifyContent:FlexAlign.Center}) {
          Button(this.btnLogin, { type: ButtonType.Normal, stateEffect: true })
            .borderRadius(18)
            .backgroundColor(0x317aff)
            .width(90)
            .height(40)
            .margin({ top: 50 })
            .onClick(() => {
              ...
              // 密码为空,气泡提示
              if (this.pass == "") {
                this.handlePopup_pass = !this.handlePopup_pass
              }
              ...
            })
            ...
        }
      }
    }
  }
}

2、逻辑设计

关于此处的RoutersetTimeout,主攻前端的小伙伴肯定不陌生,科班学习的小伙伴多少也有印象,这里我就简单讲一下。

(1)Router

Router(路由):在应用程序中实现不同页面之间的跳转和数据传递

  • 第一步:声明URL
    在这里插入图片描述

  • 第二步:跳转并传递数值

import router from '@ohos.router';

// 弹出登录成功的信息
...

@Entry
@Component
struct Index {

  ...

  // 创建构造器
  ...

  build() {
    Row() {
      Column() {
        ...
        // btn
        Flex({justifyContent:FlexAlign.Center}) {
          Button(this.btnLogin, { type: ButtonType.Normal, stateEffect: true })
            .borderRadius(18)
            .backgroundColor(0x317aff)
            .width(90)
            .height(40)
            .margin({ top: 50 })
            .onClick(() => {
              ...
              router.push({
                    url: 'pages/UserInfo',
                    // 传递数值
                    params: {
                      name: this.name,
                      pass: this.pass
                    }
              })
            })
        }
      }
    }
  }
}
  • 第三步:被选定界面,接收数值
import router from '@ohos.router';

@Entry
@Component
struct UserInfo {

  // 接收数据
  @State name: string = router.getParams()?.['name'];
  @State pass: string = router.getParams()?.['pass'];

  build() {
    Row() {
      Column(){
        Text("账号:" + this.name).fontSize(50)
        Text("密码:" + this.pass).fontSize(50)
        Button('返回')
          .onClick(() => {
            router.back()
          })
      }
    }
  }

}

(2)setTimeout

setTimeout(定时器):指定多久后(ms)完成方法(function)

setTimeout(() => {
  // 关闭自定义弹窗
  this.dialogController.close()
  // 路由跳转
  router.push({
    url: 'pages/UserInfo',
    params: {
      name: this.name,
      pass: this.pass
    }
  })
}, 1000)

三、附件

1、完整代码

  • Index.ets
import router from '@ohos.router';

// 弹出登录成功的信息
@CustomDialog
struct CustomDialogExample {
  controller: CustomDialogController
  build() {
    Column() {
      Text('登录成功')
        .fontSize(20)
        .margin({ top: 10, bottom: 10 })
        .borderRadius(5)
    }
  }
}

@Entry
@Component
struct Index {

  @State name: string = ""
  @State pass: string = ""
  @State btnLogin: string = "登录"
  @State handlePopup_name: boolean = false
  @State handlePopup_pass: boolean = false
  @State handlePopup_btn: boolean = false

  // 创建构造器
  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialogExample({}),
  })

  build() {
    Row() {
      Column() {
        // person
        Image($r('app.media.person')).width(100).height(100).margin({top:80, bottom:50})
        // data
        TextArea({ placeholder : "账号/电话号码"})
          .margin(15)
          .onChange((value: string) => {
            this.name = value
            this.handlePopup_name = false
            this.handlePopup_btn = false
          })
          .bindPopup(this.handlePopup_name, {
            message: '账号为空',
          })
        TextInput({ placeholder : "密码", text : this.pass})
          .margin(15)
          .type(InputType.Password)
          .onChange((value: string) => {
            this.pass = value
            this.handlePopup_pass = false
            this.handlePopup_btn = false
          })
          .bindPopup(this.handlePopup_pass, {
            message: '密码为空',
          })
        // btn
        Flex({justifyContent:FlexAlign.Center}) {
          Button(this.btnLogin, { type: ButtonType.Normal, stateEffect: true })
            .borderRadius(18)
            .backgroundColor(0x317aff)
            .width(90)
            .height(40)
            .margin({ top: 50 })
            .onClick(() => {
              if (this.name == "") {
                this.handlePopup_name = !this.handlePopup_name
              } else if (this.pass == "") {
                this.handlePopup_pass = !this.handlePopup_pass
              } else if (this.name == "123456" && this.pass == "666") {
                console.log("登录成功!")
                this.dialogController.open()
                // 定时任务,跳转到第二个界面,两秒后
                setTimeout(() => {
                  // 关闭自定义弹窗
                  this.dialogController.close()
                  // 路由跳转
                  router.push({
                    url: 'pages/UserInfo',
                    params: {
                      name: this.name,
                      pass: this.pass
                    }
                  })
                }, 1000)
              } else {
                this.handlePopup_btn = !this.handlePopup_btn
              }
            })
            .bindPopup(this.handlePopup_btn, {
              message: '账号或密码错误',
            })
        }
      }
    }
  }
}
  • UserInfo.ets
import router from '@ohos.router';

@Entry
@Component
struct UserInfo {

  @State name: string = router.getParams()?.['name'];
  @State pass: string = router.getParams()?.['pass'];

  build() {
    Row() {
      Column(){
        Text("账号:" + this.name).fontSize(50)
        Text("密码:" + this.pass).fontSize(50)
        Button('返回')
          .onClick(() => {
            router.back()
          })
      }
    }
  }

}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

云端new守夜人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值