【图尔科技(宁)】电竞快览(ArkUI版) 原创 精华
【本文正在参与优质创作者激励】
前言
为了能够进一步对OpenHarmony3.0内置应用做修改,我需要先掌握ArkUI声明式开发范式的相关知识。通过电竞快览应用示例能够快速学习ArkUI声明式开发,并对相关知识点进行扩展学习,最终达到对组件、布局、动效和数据状态管理的初步掌握,并将最终的健康饮食应用程序安装到烧录了OpenHarmony3.0的Hi3516开发板上。
ArkUI是一套构建HarmonyOS应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时预览工具,帮助您提升HarmonyOS应用界面开发效率30%。您只需使用一套TS/JS API,就能在多个HarmonyOS设备上提供生动而流出的用户界面体验。 ——引自HarmonyOS应用开发官网
准备
- DevEco Studio 3.0 Beta1
- OpenHarmony SDK 3.0
- 数据来源于天行数据API
通过电竞快览应用学ArkUI
1. 创建电竞快览应用(OpenHarmony版)
-
配置OpenHarmony SDK
打开DevEco Studio,点击左下角Configure,选择Setting进入设置界面。在SDK Manager菜单下选择OpenHarmony SDK,自定义存放路径,并勾选安装Platforms下的SDK及Tools下的Previewer和Toolchains。
-
点击Create Project创建项目
-
在Choose Your Ability Template界面下拉到最底部,选择
[Standard]Empty Ability
模板
-
配置工程界面完善项目信息
Project name
:项目名称
Project type
:项目类型
Bundle name
:包名称
Save location
:项目保存地址
Language
:选择编程语言(eTS)
Compatible API version
:选择兼容版本(API Version 7)
Device type
:设备类型(Phone)
点击Finish,等待项目构建完成。 -
目录结构说明
app.ets
全局应用逻辑和应用生命周期管理。
pages
存放所有组件页面。
common
存放公共代码(可选)。
resources
存放资源配置文件。 -
删除
config.json
文件中js
->pages
标签下的pages/second
-
删除
index.ets
文件中的一些代码,如图所示
-
删除
second.ets
文件
2. 术语
-
认识
@Entry
用@Entry
装饰的自定义组件用作页面的默认入口组件,加载页面时,将首先创建并呈现@Entry
装饰的自定义组件。单个源文件中,可以存在多个自定义组件,但最多可以使用@Entry
装饰一个自定义组件。 -
认识
@Component
在声明式UI中,所有的页面都是由组件构成。使用@Component
装饰的struct
表示该结构体具有组件化能力,能够成为一个独立的组件,这种类型的组件也称为自定义组件。 -
build
函数
build
函数用于定义组件的声明式UI描述。 -
认识
@Builder
@Builder
装饰器定义了一个如何渲染自定义组件的方法。通过其可以在一个自定义组件内快速生成多个布局内容。比如要在一个页面显示多个名称,使用多个Text
组件显得代码臃肿且冗余,使用@Builder
定义一个公用的方法,在组件中引入,代码量少且达到了复用。
3. 构建电竞新闻列表
::: hljs-center
:::
由图可知,整个界面分为上下两部分,上部分显示标题栏,下部分显示电竞新闻列表。
- 页面中使用的组件
1)、Column
组件
Column
组件是容器组件,是沿垂直方向布局的容器。相对的就存在沿水平方向布局的容器,其为Row
组件,这两个组件我将它们定位为线性布局容器。
可以通过alignItems
属性来设置子组件在水平方向上的对齐格式。提供了Start
、Center
、End
三种对齐方式。
Column() {
//子组件
}
.alignItems(HorizontalAlign.Center)
2)、Flex
组件
Flex
是弹性布局组件,其提供五个属性来控制子组件的显示方式。
Flex({direction: FlexDirection.Row,wrap: FlexWrap.NoWrap, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Stretch, alginContent: FlexAlign.Start})
direction
:描述子组件在Flex
容器上排列的方向,即主轴方向,也就是子组件是以横向排列还是纵向排列。
FlexDirection.Row
:横向(行方向)排列,从行起始位置开始。
FlexDirection.RowReverse
:横向(行方向)排列,与Row
方向相反,即从行尾开始排列。
FlexDirection.Column
:纵向(列方向)排列,从列起始位置开始。
FlexDirection.ColumnReverse
:纵向(列方向)排列,与Column
方向相反,即从列尾开始排列。
Flex({direction: FlexDirection.Row}) {}
Flex({direction: FlexDirection.RowReverse}) {}
Flex({direction: FlexDirection.Column}) {}
Flex({direction: FlexDirection.ColumnReverse}) {}
wrap
: Flex容器中子组件是单行/列还是多行/列排列。
justifyContent
:子组件在Flex容器主轴上的对齐格式。
alignItems
:子组件在Flex容器交叉轴上的对齐格式。
alignContent
:交叉轴中有额外的空间时,多行内容的对齐方式。仅在wrap
为Wrap
或WrapReverse
下生效。
3)、List
组件
List
组件用于显示一系列相同宽度的列表项,比如显示新闻列表、商品列表等。List
组件和ListItem
组件一起使用。ListItem
用于展示具体的数据项。
List() {
ListItem() {
//组合数据项
}
ListItem() {
//组合数据项
}
}
4)、Text
组件
Text
用于呈现一段信息。
Text(){}
5)、Image
组件
Image
组件用于渲染展示图片。
Image(){}
-
通用组件属性和事件
width()
:设置组件自身的宽度。
height()
:设置组件自身的高度。
margin()
:设置外边距属性。
padding()
:设置内边距属性。
backgroundColor
:设置组件的背景色。
borderRadius
:设置元素的边框圆角半径。 -
和搭积木一样,把需要的组件组装到一起,完成列表页的构建。
import router from '@system.router';
import {ESports} from '../model/ESports.ets';
import {initOnStartup} from '../model/ESportsList.ets';
@Component
struct ESportsListItem {
private eSportsItem: ESports
build() {
Flex({justifyContent:FlexAlign.Start, alignItems: ItemAlign.Center}) {
Image(this.eSportsItem.picUrl)
.objectFit(ImageFit.Contain)
.height('100%')
.width(120)
.margin({right: 16, left: 16})
Column() {
Text(this.eSportsItem.title)
.fontSize(14)
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
Text(this.eSportsItem.description)
.fontSize(12)
.fontColor('#cccccc')
.maxLines(2)
.textOverflow({overflow: TextOverflow.Ellipsis})
.margin({top: 10})
}
.padding(4)
}
.height(100)
.backgroundColor(0xF5F5F5)
.borderRadius(8)
}
}
@Entry
@Component
struct Index {
private eSportsItems: ESports[] = initOnStartup()
build() {
Column() {
Flex({justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center}) {
Text('电竞快览')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin(20)
}
List({space: 4, initialIndex: 0}) {
ForEach(this.eSportsItems, item => {
ListItem() {
ESportsListItem({eSportsItem: item})
}
.onClick(() => {
router.push({
uri: 'pages/content',
params: {eSports: item}
})
})
}, item => item.id.toString())
}
.width('96%')
}
.width("100%")
.height("100%")
.backgroundColor(0xE5E5E5)
.padding({top: 5})
}
}
4. 构建电竞新闻内容
import router from '@system.router';
import {ESports} from '../model/ESports.ets';
@Component
struct PageTitle {
private eSports: ESports;
build() {
Flex({alignItems: ItemAlign.Start}) {
Image($r('app.media.back'))
.width(20)
.height('100%')
Text(this.eSports.title)
.height('100%')
.fontSize(16)
.fontWeight(FontWeight.Bold)
.maxLines(1)
.textOverflow({overflow: TextOverflow.Ellipsis})
.margin({left: 16})
}
.height(61)
.backgroundColor('#FFedf2f5')
.padding({top: 13, bottom: 14, left: 12})
.onClick(() => {
router.back();
})
}
}
@Entry
@Component
struct Content {
private eSports: ESports = router.getParams().eSports;
build() {
Column() {
Stack({alignContent: Alignment.TopStart}) {
PageTitle({eSports: this.eSports})
}
Column() {
Text(this.eSports.title)
.width('80%')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.maxLines(2)
.textOverflow({overflow: TextOverflow.Ellipsis})
.textAlign(TextAlign.Center)
.padding({top: 8, bottom: 8})
Row({space: 12}) {
Text(this.eSports.source)
.fontSize(12)
.fontColor('#CCCCCC')
Text(this.eSports.ctime)
.fontSize(12)
.fontColor('#CCCCCC')
}
.margin({top: 5, bottom: 10})
Text(this.eSports.description)
.width('90%')
.height(80)
.lineHeight(20)
.fontSize(12)
.maxLines(5)
.textOverflow({overflow: TextOverflow.Ellipsis})
.borderRadius(10)
.backgroundColor(0xE5E5E5)
.padding(10)
}
}
.alignItems(HorizontalAlign.Center)
.height('100%')
.width('100%')
}
}
==这里预留一个思考题:==
新闻内容是使用文本编辑器或者直接使用的是URL链接地址,如何让它能够在页面中直接显示?有兴趣的可以在评论区留言一起讨论^_^。
参考
[1] ArkUI介绍
[2] ArkUI API介绍
[3] ArkUI 健康饮食应用
源码地址
【本文正在参与优质创作者激励】
第一时间阅读白老师文章
学习,老师讲的很详细。
ArkUI开发确实很方便
谢谢认可!ArkUI框架的详细介绍正在规划中,持续关注我^_^
持续关注老师!
good good