元服务———页面基础布局
1、页面创建
新创建一个项目
初始创建完成后,可以看到pages中只有一个index.ets页面
继续创建新页面(pages(鼠标右键)>New>ArkTS File)
输入ArkTS File名称
创建完毕后效果:
我们来写一下基础页面结构
@Entry
@Component
struct Secondpage{
build() {
}
}
再把index.ets的内容粘贴过来即可,记得改一下名称和字符串
2、router 路由
概述 路由用于管理应用程序中的不同页面或者视图之间的导航。它就像是一张地图,指引用户(或者应用内部的逻辑)从一个地方(页面)到另一个地方。路由系统通常由一系列的路由规则组成,这些规则定义了 URL 路径(在 Web 应用中)或者某种导航标识符(在非 Web 应用中,如移动应用)与对应的组件或者页面之间的关联,在HarmonyOS开发中一般页面路由在src > main > resources > base > main_pages.json中设置。
使用 我们将页面的信息都写到 src/main/resources/base/main_pages.json 中。
添加路由跳转代码
页面:index.ets
import { authentication } from '@kit.AccountKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { router } from '@kit.ArkUI'
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('HelloWorld')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
Button("跳转第二页").width('100%').height(80).onClick((event: ClickEvent) => {
router.pushUrl({ url: 'pages/SecondPage' })
}).margin({ top: 200 })
}
.height('100%')
.width('100%')
}
aboutToAppear() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
this.loginWithHuaweiID();
}
/**
* Sample code for using HUAWEI ID to log in to atomic service.
* According to the Atomic Service Review Guide, when a atomic service has an account system,
* the option to log in with a HUAWEI ID must be provided.
* The following presets the atomic service to use the HUAWEI ID silent login function.
* To enable the atomic service to log in successfully using the HUAWEI ID, please refer
* to the HarmonyOS HUAWEI ID Access Guide to configure the client ID and fingerprint certificate.
*/
private loginWithHuaweiID() {
// Create a login request and set parameters
let loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();
// Whether to forcibly launch the HUAWEI ID login page when the user is not logged in with the HUAWEI ID
loginRequest.forceLogin = false;
// Execute login request
let controller = new authentication.AuthenticationController();
controller.executeRequest(loginRequest).then((data) => {
let loginWithHuaweiIDResponse = data as authentication.LoginWithHuaweiIDResponse;
let authCode = loginWithHuaweiIDResponse.data?.authorizationCode;
// Send authCode to the backend in exchange for unionID, session
}).catch((error: BusinessError) => {
hilog.error(0x0000, 'testTag', 'error: %{public}s', JSON.stringify(error));
if (error.code == authentication.AuthenticationErrorCode.ACCOUNT_NOT_LOGGED_IN) {
// HUAWEI ID is not logged in, it is recommended to jump to the login guide page
}
});
}
}
页面:SecondPage.ets
import { router } from '@kit.ArkUI'
@Entry
@Component
struct SecondPage {
@State message: string = '第二个页面';
build() {
RelativeContainer() {
Text(this.message)
.id('SecondPage')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
Button("跳转第一页").width('100%').height(80).onClick((event: ClickEvent) => {
router.pushUrl({ url: 'pages/Index' })
}).margin({ top: 200 })
}
.height('100%')
.width('100%')
}
}
效果:
布局
布局概述
组件按照布局的要求依次排列,构成应用的页面。在声明式UI中,所有的页面都是由自定义组件构成,开发者可以根据自己的需求,选择合适的布局进行页面开发。
布局指用特定的组件或者属性来管理用户页面所放置UI组件的大小和位置。在实际的开发过程中,需要遵守以下流程保证整体的布局效果:
- 确定页面的布局结构。
- 分析页面中的元素构成。
- 选用适合的布局容器组件或属性控制页面中各个元素的位置和大小。
布局结构
布局通常为分层结构,一个常见的页面结构如下所示:
为实现上述效果,开发者需要在页面中声明对应的元素。其中,Page表示页面的根节点,Column/Row等元素为系统组件。针对不同的页面结构,ArkUI提供了不同的布局组件来帮助开发者实现对应布局的效果,例如Row用于实现线性布局。
布局元素的组成
布局相关的容器组件可形成对应的布局效果。例如,List组件可构成线性布局。
-
组件区域(蓝区方块):**组件区域表示组件的大小,width、height属性用于设置组件区域的大小。
-
组件内容区(黄色方块):**组件内容区大小为组件区域大小减去组件的border值,组件内容区大小会作为组件内容(或者子组件)进行大小测算时的布局测算限制。
-
组件内容(绿色方块):**组件内容本身占用的大小,比如文本内容占用的大小。组件内容和组件内容区不一定匹配,比如设置了固定的width和height,此时组件内容的大小就是设置的width和height减去padding和border值,但文本内容则是通过文本布局引擎测算后得到的大小,可能出现文本真实大小小于设置的组件内容区大小。当组件内容和组件内容区大小不一致时,align属性生效,定义组件内容在组件内容区的对齐方式,如居中对齐。
-
组件布局边界(虚线部分):**组件通过margin属性设置外边距时,组件布局边界就是组件区域加上margin的大小。
构建布局
我们主要掌握的有:线性布局、层叠布局、弹性布局、相对布局、栅格布局,那么接下来我们就理论与实操一起上,争取快速掌握。 布局容器:具有布局能力的容器组件,可以承载其他元素作为其子元素,布局容器会对其子元素进行尺寸计算和布局排列。
-
布局子元素:布局容器内部的元素。
-
主轴:线性布局容器在布局方向上的轴线,子元素默认沿主轴排列。Row容器主轴为水平方向,Column容器主轴为垂直方向。
-
交叉轴:垂直于主轴方向的轴线。Row容器交叉轴为垂直方向,Column容器交叉轴为水平方向。
-
间距:布局子元素的间距。
注:【.justifyContent(FlexAlign.Center)】代表元素在垂直方向方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同,为了更好做图片效果,后面很多示例都单独加了这个,可以自定义去掉这个代码块再看效果。
线性布局
线性布局(LinearLayout)是开发中最常用的布局,通过线性容器Row和Column构建。线性布局是其他布局的基础,其子元素在线性方向上(水平方向和垂直方向)依次排列。线性布局的排列方向由所选容器组件决定,Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。根据不同的排列方向,开发者可选择使用Row或Column容器创建线性布局。
实例:
Column
@Entry
@Component
struct TestPage {
build() {
Column(){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
ROW
@Entry
@Component
struct TestPage {
build() {
Row(){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
布局子元素在排列方向上的间距
在布局容器内,可以通过【space】属性设置排列方向上子元素的间距,使各子元素在排列方向上有等间距效果。
@Entry
@Component
struct TestPage {
build() {
Row({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
}
}
容器内子元素在水平方向上的排列
Column
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Start)
}
}
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.End)
}
}
Row Row用到的对象是VerticalAlign,其属性有3种:
-
VerticalAlign.Top:子元素在垂直方向顶部对齐。
-
VerticalAlign.Center:默认状态,子元素在垂直方向居中对齐。
-
VerticalAlign.Bottom:子元素在垂直方向底部对齐。
@Entry
@Component
struct TestPage {
build() {
Row({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Top)
}
}
@Entry
@Component
struct TestPage {
build() {
Row({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Bottom)
}
}
布局子元素在主轴上的排列方式:Column
在布局容器内,可以通过justifyContent属性设置子元素在容器主轴上的排列方式。可以从主轴起始位置开始排布,也可以从主轴结束位置开始排布,或者均匀分割主轴的空间。
- justifyContent(FlexAlign.Start):元素在垂直方向方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。
- justifyContent(FlexAlign.Center):元素在垂直方向方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同。
- justifyContent(FlexAlign.End):元素在垂直方向方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。
- justifyContent(FlexAlign.SpaceBetween):垂直方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐。
- justifyContent(FlexAlign.SpaceAround):垂直方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
- justifyContent(FlexAlign.SpaceEvenly):垂直方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Start)
}
}
@Entry
@Component
struct TestPage {
![image-20241106111114019.png](https://api.nutpi.net/file/topic/2024-11-27/image/53fac981b0b941b4a68d02780a38e66cb1695.png)
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.End)
}
}
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.SpaceBetween)
}
}
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.SpaceAround)
}
}
@Entry
@Component
struct TestPage {
build() {
Column({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
Text("四季平安").fontSize(15).width(65).height(50).backgroundColor(Color.Blue)
Text("五福臨門").fontSize(15).width(65).height(50).backgroundColor(Color.White)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.SpaceEvenly)
}
}
布局子元素在主轴上的排列方式:Row
- justifyContent(FlexAlign.Start):元素在水平方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。
- justifyContent(FlexAlign.Center):元素在水平方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同。
- justifyContent(FlexAlign.End):元素在水平方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。
- justifyContent(FlexAlign.SpaceBetween):水平方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐。
- justifyContent(FlexAlign.SpaceAround):水平方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
- justifyContent(FlexAlign.SpaceEvenly):水平方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样。
@Entry
@Component
struct TestPage {
build() {
Row({ space: 7 }){
Text("一帆風順").fontSize(15).width(65).height(50).backgroundColor(Color.Red)
Text("二龍騰飛").fontSize(15).width(65).height(50).backgroundColor(Color.Gray)
Text("三羊開泰").fontSize(15).width(65).height(50).backgroundColor(Color.Yellow)
}.backgroundColor("#66CCFF").width('100%').height('100%').justifyContent(FlexAlign.Start)
}
}