预览
简介
基于鸿蒙系统(HarmonyOS)开发的现代化登录界面,采用了科技感十足的红色主题设计。该界面结合了流畅的动画效果、精心设计的视觉元素和人性化的交互体验,为用户提供了一个安全、美观且易用的登录入口。
🎨 精美视觉设计
- 科技感红色主题:采用鲜明的红色调作为主色调,搭配半透明背景和模糊效果,营造出强烈的视觉冲击力
- 精致的UI元素:包含精心设计的输入框、按钮、分割线和装饰元素
- 动态视觉效果:融入了细腻的动画和过渡效果,提升用户体验
🛠️ 实用功能
- 用户名/密码登录:支持传统的账号密码登录方式
- 密码可见性切换:用户可以切换密码的显示/隐藏状态
- 短信验证码:集成了验证码获取功能,包含60秒倒计时
- 表单验证:内置基础的表单验证逻辑,确保输入完整性
🔄 交互体验
- 输入框焦点动画:当用户聚焦于输入框时,会触发微妙的缩放动画
- 按钮状态反馈:按钮会根据不同状态展示不同的视觉效果
- 友好的错误提示:使用对话框提供清晰的错误提示信息
技术亮点
- 基于ArkTS语言:采用鸿蒙系统原生开发语言,性能优异
- 声明式UI:使用ArkUI框架的声明式UI开发方式,代码简洁高效
- 响应式设计:界面元素能够适应不同尺寸的设备屏幕
- 状态管理:使用@State装饰器管理组件状态,实现UI与数据的同步
- 动画系统:利用鸿蒙系统的动画API实现流畅的交互效果
使用场景
- 移动应用的用户登录界面
- 企业内部系统的身份验证入口
- 智能设备的用户认证界面
- 需要安全登录的各类应用场景
源码
@Entry
@Component
struct Index {
@State username: string = ''
@State password: string = ''
@State verificationCode: string = ''
@State countdown: number = 60
@State isCounting: boolean = false
private intervalID: number = -1
@State private rotateAngle: number = 0
private rotateTimer: number = -1
aboutToAppear() {
// 启动旋转动画
this.rotateTimer = setInterval(() => {
this.rotateAngle = (this.rotateAngle + 1) % 360
}, 50)
}
aboutToDisappear() {
// 清除定时器
if (this.intervalID !== -1) {
clearInterval(this.intervalID)
}
if (this.rotateTimer !== -1) {
clearInterval(this.rotateTimer)
}
}
// 开始倒计时
startCountdown() {
if (this.isCounting) {
return
}
this.isCounting = true
this.countdown = 60
this.intervalID = setInterval(() => {
this.countdown--
if (this.countdown <= 0) {
this.isCounting = false
clearInterval(this.intervalID)
}
}, 1000)
}
// 模拟登录
login() {
if (!this.username.trim()) {
AlertDialog.show({
title: '提示',
message: '请输入用户名',
confirm: {
value: '确定',
action: () => {
console.info('用户确认')
}
}
})
return
}
if (!this.password.trim()) {
AlertDialog.show({
title: '提示',
message: '请输入密码',
confirm: {
value: '确定',
action: () => {
console.info('用户确认')
}
}
})
return
}
if (!this.verificationCode.trim()) {
AlertDialog.show({
title: '提示',
message: '请输入验证码',
confirm: {
value: '确定',
action: () => {
console.info('用户确认')
}
}
})
return
}
AlertDialog.show({
title: '登录成功',
message: '欢迎回来,' + this.username,
confirm: {
value: '确定',
action: () => {
console.info('登录成功')
}
}
})
}
build() {
Stack({ alignContent: Alignment.Center }) {
// 背景
Column()
.width('100%')
.height('100%')
.backgroundImage($r('app.media.background'))
.backgroundImageSize(ImageSize.Cover)
// 半透明红色遮罩层,增强视觉冲击力
Column()
.width('100%')
.height('100%')
.backgroundColor('rgba(180, 0, 0, 0.5)')
// 登录表单
Column() {
// 标题
Row() {
Text('登录')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#FFFFFF')
.textShadow({
radius: 10,
color: 'rgba(226, 35, 26, 0.8)',
offsetX: 0,
offsetY: 0
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
.margin({ bottom: 40 })
// 用户名输入框
Column() {
Row() {
TextInput({ placeholder: '请输入用户名', text: this.username })
.placeholderColor('rgba(255, 255, 255, 0.6)')
.placeholderFont({ size: 16 })
.caretColor('#E2231A')
.fontColor('#FFFFFF')
.backgroundColor('transparent')
.padding({ left: 0, right: 0 })
.onChange((value) => {
this.username = value
})
.width('85%')
.height(50)
}
.width('100%')
.padding({ left: 20, right: 20 })
Divider()
.width('90%')
.height(1)
.color('rgba(226, 35, 26, 0.6)')
.margin({ top: 5 })
}
.margin({ bottom: 20 })
// 密码输入框
Column() {
Row() {
TextInput({ placeholder: '请输入密码', text: this.password })
.placeholderColor('rgba(255, 255, 255, 0.6)')
.placeholderFont({ size: 16 })
.caretColor('#E2231A')
.fontColor('#FFFFFF')
.backgroundColor('transparent')
.padding({ left: 0, right: 0 })
.type(InputType.Password)
.onChange((value) => {
this.password = value
})
.width('100%')
.height(50)
}
.width('100%')
.padding({ left: 20, right: 20 })
Divider()
.width('90%')
.height(1)
.color('rgba(226, 35, 26, 0.6)')
.margin({ top: 5 })
}
.margin({ bottom: 20 })
// 验证码输入框
Column() {
Row() {
TextInput({ placeholder: '请输入验证码', text: this.verificationCode })
.placeholderColor('rgba(255, 255, 255, 0.6)')
.placeholderFont({ size: 16 })
.caretColor('#E2231A')
.fontColor('#FFFFFF')
.padding({ left: 0, right: 0 })
.backgroundColor('transparent')
.type(InputType.Number)
.onChange((value) => {
this.verificationCode = value
})
.width('55%')
.height(50)
Button(this.isCounting ? `${this.countdown}秒后重试` : '获取验证码')
.fontSize(14)
.fontWeight(FontWeight.Medium)
.fontColor(this.isCounting ? '#999999' : '#FFFFFF')
.backgroundColor(this.isCounting ? 'rgba(0, 0, 0, 0.3)' : 'rgba(226, 35, 26, 0.6)')
.width(120)
.height(40)
.borderRadius(20)
.enabled(!this.isCounting)
.onClick(() => {
this.startCountdown()
})
}
.width('100%')
.padding({ left: 20, right: 20 })
Divider()
.width('90%')
.height(1)
.color('rgba(226, 35, 26, 0.6)')
.margin({ top: 5 })
}
.margin({ bottom: 40 })
// 登录按钮
Button('登 录')
.width('90%')
.height(50)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.borderRadius(25)
.backgroundColor('rgba(226, 35, 26, 0.6)')
.fontColor('#FFFFFF')
.onClick(() => {
this.login()
})
}
.width('90%')
.padding({
top: 40,
bottom: 40,
left: 10,
right: 10
})
.borderRadius(15)
.backgroundColor('rgba(40, 0, 0, 0.8)')
.backdropBlur(10)
.border({ width: 1, color: 'rgba(255, 50, 50, 0.5)' })
}
.width('100%')
.height('100%')
}
}