前言
学习鸿蒙的 ArkUI 框架有一段时间了,基础组件和容器组件也学了个七七八八。下面通过实战一个授权页面来梳理一下学过的组件。效果图如下:
涉及的组件如下:
- 容器组件:Row、Column、Stack。
- 基础组件:Image、Text、Button、Blank。
- 提示组件:AlertDialog、promptAction。
可以看到,虽然是一个看上去比较简单的页面,但用到的组件还是不少的,下面让我们开始编写代码。
定义模型
因为这是一个应用的授权页面,所以首先我们要自定义一个数据模型来表示应用,代码如下:
ini
class AppModel {
name: string;
icon: string;
test: boolean;
authedTime: number;
constructor(name: string, icon: string, test: boolean, authedTime: number) {
this.name = name;
this.icon = icon;
this.test = test;
this.authedTime = authedTime;
}
}
需要注意的是,构造方法是可以使用快捷键 command+N
来自动生成的,不需要我们一个一个的再去写。
授权时间的转换
在存储时间相关的信息时,一般都会使用时间戳来存储,显示的时候是字符串。所以需要一个转换方法来实现 number 到 string:
typescript
/**
* 获取授权时间的字符串
* @returns 授权时间的字符串
*/
private convertTimeToDateString(): string {
if (!this.app) {
return '';
}
const date = new Date(this.app?.authedTime);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}`;
}
页面
首先,因为该页面是纵向布局的,所以我们最外层的容器组件使用的是 Column
:
scss
build() {
Column() { }
.height('100%')
.width('100%')
.padding({left: 16, right: 16})
}
该布局的宽高占满屏幕的宽高,为了视图效果更加美观。给 Column 的左右内边距设置为 16。
头部展示
然后是头部授权应用的信息展示部分: 代码如下:
scss
Row() {
Row() {
Stack({ alignContent: Alignment.TopEnd }) {
Image(this.app?.icon)
.width(72)
.height(72)
.borderRadius(8)
.alt($r('app.media.alt_img'))
Image($r('app.media.img'))
.width(28)
.height(28)
.visibility(this.app?.test ? Visibility.Visible : Visibility.Hidden)
}
.width(72)
.height(72)
Text(this.app?.name)
.fontSize(18)
.fontWeight(FontWeight.Bold)
.padding({left: 16})
}
Text("已授权")
.fontSize(16)
.fontColor(Color.Black)
}
.width('100%')
.height(148)
.justifyContent(FlexAlign.SpaceBetween)
.alignItems(VerticalAlign.Center)
该部分是水平布局,所以最外层是一个 Row。它的宽度占满屏幕,高度为 148。它的主轴布局规则为 SpaceBetween
(官方文档解释:Flex主轴方向均匀分配弹性元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐。),纵向布局则是居中。
左边部分也是一个 Row,里面包含一个应用 icon 展示和应用名称显示。右边则是文本展示。
因为左边的应用icon上需要展示一个是否为测试应用的图标,所以使用了 Stack
容器组件。它的布局方式为右上角对齐:TopEnd。组件的是否可见用 visibility
来控制。
授权信息展示
这一部分比较简单,就是 Row 和 Text 组件的使用:
scss
Blank()
.height(12)
Row() {
Text("授权时间")
.fontSize(16)
Text(this.convertTimeToDateString())
.fontSize(16)
.fontColor(Color.Gray)
}
.width('100%')
.height(48)
.justifyContent(FlexAlign.SpaceBetween)
Row() {
Text("授权内容")
.fontSize(16)
Text("获取你的公开信息")
.fontSize(16)
.fontColor(Color.Gray)
}
.width('100%')
.height(48)
.justifyContent(FlexAlign.SpaceBetween)
同样,为了布局的美观性,使用了 Blank
组件进行空隙设置。
底部按钮
底部则是一个按钮的展示:
scss
Blank()
Button("删除授权")
.width('100%')
.onClick(() => {
this.showAlter();
})
可以看到,这里添加了一个没有指定高度的 Blank 组件,它的作用是将按钮给挤到底部。如果不给它设置高度,Blank 组件,在容器主轴方向上,具有自动填充容器空余部分的能力。仅当父组件为Row/Column/Flex时生效。
因为 ArkUI 的组件排布默认是相邻排布的,如果不添加 Blank 组件,按钮则会靠很上面。如下图的效果:
点击事件的处理
最后,就是按钮点击事件的处理了:
php
private showAlter() {
AlertDialog.show(
{
title: "删除授权后再次授权才可使用",
message: '',
autoCancel: true,
alignment: DialogAlignment.Center,
primaryButton: {
fontColor: Color.Black,
value: "取消",
action: () => {}
},
secondaryButton: {
fontColor: Color.Blue,
value: "确认",
action: () => {
promptAction.showToast({message:"已删除成功", duration: 2000})
}
}
}
)
}
点击按钮展示一个确认删除的 Dialog,点击 Dialog 的确认按钮,弹出删除成功的 toast 提示。