鸿蒙基础-基础环境-ArkTS-组件-样式
DevEcoStudio编辑器下载链接
链接: https://pan.baidu.com/s/18C9i35YPh4GsHpbSif8KQw?pwd=d6e9 提取码: d6e9
安装教程
下载对应的版本
- windows
- mac英特尔
- mac Arm
API12 的编辑器
API12的模拟器(mac英特尔安装API11)
- Mac Arm芯片版本安装
解压编辑器版本
将左侧内容拖入
点击打开
- 打开项目的配置项
新建一个路径 HarmonyOS-SDK
将资源下载包中的sdk的内容进行解压,放入到刚刚新建的目录
将设置中的安装路径改变成新建的目录,最终点击确认,sdk就安装好了
打开原有项目发现
一个配置文件的依赖,线上没有提供云下载地址,只能采用离线的版本 。hvigor
下载资源包中,还有提供一个dependencies, 这就是我们需要替换的版本
安装模拟器
- 需要实名登录
- 安装插件
internal-plugin-SNAPSHOT.zip
如果大家的mac安装不上 这个插件,可以采用文档中提供的,下载之后安装即可
下载资源中的模拟器,拷贝到sdk的目录
注意: 模拟器的名字是小写的
- 创建镜像目录
注意
** 如果用的是API12的模拟器,需要把镜像放入到HarmonyOS-NEXT-DB1 目录下。**
** 如果用的是API11的模拟器,需要把镜像放入到HarmonyOS-NEXT-DP2 目录下。**
system-image
HarmonyOS-NEXT-DB1
phone_arm/phone_x86
HarmonyOS-NEXT-DP2
phone_arm/phone_x86
Windows安装模拟器
起步
起步-鸿蒙简介
- HarmonyOS 是新一代的智能终端操作系统,为不同设备的智能化、互联与协同提供了统一的语言。带来简洁,流畅,连续,安全可靠的全场景交互体验。
历程:
时间 | 事件 |
---|---|
2019 | HarmonyOS 1.0,华为在东莞举行华为开发者大会,正式发布操作系统鸿蒙 OS,主要用于物联网 |
2020 | HarmonyOS 2.0,基于开源项目 OpenHarmony 开发的面向多种全场景智能设备的商用版本 |
2021 | HarmonyOS 3.0,先后优化游戏流畅度、地图三维体验、系统安全,另外系统的稳定性也得到了增强 |
2023.2 | HarmonyOS 3.1,系统纯净能力进一步提升,对后台弹窗、 隐藏应用、后台跳转等情况 |
2023.7 | 华为 Mate 50 系列手机获推 HarmonyOS 4.0 |
2024 | HarmonyOS Next 开发者预览版发布,将不在兼容安卓应用 |
起步-DevEco Studio
安装 DevEco Studio 编辑器
DevEcoStudio编辑器下载链接
链接: https://pan.baidu.com/s/1TyrmbTkrOEsTB8HcaMR4og?pwd=fjjw 提取码: fjjw
- 安装:DevEco Studio → 一路 Next(只演示windows)
- 运行: 选择not import System Img
这里最好别选在C盘
- 下一步
- 下载sdk
- 安装完成
- 安装完成
- 创建一个新项目
- 填写信息
等待创建完成
- 安装中文插件(windows)
- Mac的选择
- 选择Plugins
- 点OK重启
- 看到效果
起步-认识工作区
- 通过左侧目录找到对应的应用文件,在编辑区进行代码编写,在右侧看预览效果
- 连按两下shift,可以快速寻找文件
起步-如何排错
写代码时,我们会经常遇到这种情况,右侧出现不能够开启预览器的提示,让我们打开预览器日志看错误
- 解决该问题的思路 1. 按照编辑器提示的,打开预览器日志
- 如果是明确的语法错误或者api错误,编辑器会指出我们代码的行数,我们可以点击提示的代码行,直接跳到对应位置,直接检查代码的问题
- 跳到对应的位置
解决思路2: 如果当前文件不多,可以点开你创建的所有文件,查看文件中是否有报错的地方,文件报错,在右侧以及代码区会有明显的报错提示
解决思路3: 通过统一构建,暴露哪些文件及代码无法编译通过
如何刷新看效果
预览器是有热更新的
- 原则上写完右侧自动更新
- 如果不自动刷新- 语法错了,编辑器卡住了
- 直接点击刷新按钮
- 刷新只能针对 带有@Entry和@Preview的文件,否则无法看到效果
起步-审查和多设备预览
效果预览方法:
info
- Preview(预览器)
- 本地模拟器(只有Mac(ARM)芯片)
远程模拟器云手机(需要审核及申请,暂无消息)- 本地真机(Meta60-Meta60Pro X5或者是装载OpenHarmony的工程机(价格较低,但是依然存在一些问题))
danger
只有装了Next预览版系统的手机才可以进行真机调试和预览,目前Next预览器系统装机量有限,需要申请和审核,小道消息Q2季度会进一步扩大开放名额
- 预览器的多设备预览
danger
2in1的意思是 平板电脑二合一的状态
- 审查元素
- 真机预览调试
info
-
刷了Next预览版本的手机插上数据线,连接到电脑之后(注意:这里需要开启手机的usb调试,设置中搜索usb调试,打开,并且处理开发者模式,打开手机设置-关于手机,连续点击手机系统的版本号,直到出现您已处于开发者模式的提示未知)
-
运行
info
点击绿色三角- 运行到真机 -
debugger模式
info
点击小虫子-断点调试到真机(4.0版本中真机不支持断点调试-next真机支持断点调试)
起步-工程目录结构
info
我们详解下目录结构
-
AppScope > app.json5:应用的全局配置信息。
-
**entry:**应用/服务模块,编译构建生成一个HAP。
- src > main > ets:用于存放ArkTS源码。
- src > main > ets > entryability:应用/服务的入口。
- src > main > ets > pages:应用/服务包含的页面。
- **src > main > resources:**用于存放应用/服务模块所用到的资源文件,如图形、多媒体、字符串、布局文件等。
- src > main > module.json5:Stage模型模块配置文件,主要包含HAP的配置信息、应用在具体设备上的配置信息以及应用的全局配置信息。
-
**entry > build-profile.json5:**当前的模块信息、编译信息配置项,包括buildOption、targets配置等。
-
entry > hvigorfile.ts:模块级编译构建任务脚本。
-
entry >oh-package.json5:配置三方包声明文件的入口及包名。
-
oh_modules:用于存放三方库依赖信息,包含应用/服务所依赖的第三方库文件。关于原npm工程适配ohpm操作,请参考历史工程适配OHPM包管理。
-
**build-profile.json5:**应用级配置信息,包括签名、产品配置等。
-
**hvigorfile.ts:**应用级编译构建任务脚本。
-
资源目录结构
什么是Stage模型
info
通过上层的目录结构我们要分析出如下关系
State
-Module(模块-对应Hap包)
-ability(应用服务入口)
-pages(页面)
-component(自定义组件)
-resources(资源)
应用模型Stage&FA
鸿蒙的战略 兼容安卓-把java + 前端拉入到开发阵容中-FA模型
- 应用模型是HarmonyOS为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。有了应用模型,开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效。
换言之- 应用模型是鸿蒙开发一切的基础,因为只有基于该应用模型我们才可以开发对应的应用和业务。
应用模型包含几个要素**应用组件-**应用进程-应用线程-应用任务管理-应用配置文件
提问:应用模型是只有一个吗?
回答:鸿蒙前后推出了两种应用模型- FA(,Stage,目前FA已经不再主推。)Feature Ability
- HarmonyOS Next也将Stage模型作为主推模型,所以我们本次训练营将学习Stage模型相关的应用开发能力。
下面是官方的Stage模型概念图
总结:应用模型是开发鸿蒙应用的基础底座,但是鸿蒙先后推出了FA和Stage,鸿蒙4.0和鸿蒙Next都将Stage作为主推方向,所以我们主要基于Stage模型来学习和开发我们目前的应用。
什么是UIAbility-(界面能力组件)
从上一个小节中,我们发现Stage模型提到了UIAbility组件包含UI界面绘制,主要和用户交互。
- UIAbility组件是一种包含UI界面的应用组件,主要用于和用户交互。
官网介绍-UIAbility是系统调度的基本单元,可以给应用提供绘制界面的窗口。
info
UIAbility的设计理念:
- 原生支持应用组件级的跨端迁移和多端协同。
- 支持多设备和多窗口形态。
UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。
对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
如果开发者希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
如果开发者希望在任务视图中看到多个任务,或者需要同时开启多个窗口,则建议使用多个UIAbility开发不同的模块功能。
场景- 支付/小程序/鉴权
为使应用能够正常使用UIAbility,需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息。
{
"module": {
...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"srcEntry": "./ets/entryability/EntryAbility.ets", // UIAbility组件的代码路径
"description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
"icon": "$media:icon", // UIAbility组件的图标
"label": "$string:EntryAbility_label", // UIAbility组件的标签
"startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
...
}
]
}
}
warning
上述文件不用我们手动填写,我们新建ability的时候,会自动填入
组件基础
组件-什么是ArkTS
info
ArkTS提供了语言运行时相关能力
ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,保持了TS的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和性能。
特别注意:尤其是学过鸿蒙4.0的,Next版本极大增强了TS语言中动态类型的限制,几乎不再支持动态类型
从API version 10开始,ArkTS进一步通过规范强化静态检查和分析,对比标准TS的差异可以参考从TypeScript到ArkTS的适配规则:
- 强制使用静态类型:静态类型是ArkTS最重要的特性之一。如果使用静态类型,那么程序中变量的类型就是确定的。同时,由于所有类型在程序实际运行前都是已知的,编译器可以验证代码的正确性,从而减少运行时的类型检查,有助于性能提升。
- 禁止在运行时改变对象布局:为实现最大性能,ArkTS要求在程序执行期间不能更改对象布局。
- 限制运算符语义:为获得更好的性能并鼓励开发者编写更清晰的代码,ArkTS限制了一些运算符的语义。比如,一元加法运算符只能作用于数字,不能用于其他类型的变量。
- 不支持Structural typing:对Structural typing的支持需要在语言、编译器和运行时进行大量的考虑和仔细的实现,当前ArkTS不支持该特性。根据实际场景的需求和反馈,我们后续会重新考虑。
- 由于文档权限的限制,这里有一份openHarmony的 上的Next版本的ts类型的迁移说明 地址 (内容基本一致)
openHarmony 和HarmonyOS的关系和区别
OpenHarmony是指鸿蒙(HarmonyOS)的开源版本,由华为官方开源,遵循Apache 2.0许可证。OpenHarmony包含了HarmonyOS的核心代码库,但并不包括商业版HarmonyOS中的一些特有功能和技术。
HarmonyOS是华为自主研发的分布式操作系统,旨在打造一个全场景、全终端的智能生态系统。它支持多种设备类型,包括手机、平板、智能手表、智能音箱、电视、汽车、家居等,可以实现设备之间的协同工作和资源共享。
OpenHarmony和HarmonyOS的关系就像是Java和Android的关系一样。可以将OpenHarmony看作是HarmonyOS的底层技术和代码库的一部分,而HarmonyOS则是在此基础上进行了更多的开发和扩展,添加了更多的功能和应用。相比之下,OpenHarmony更加开放和自由,可以被开发者用于构建各种类型的设备和应用,而HarmonyOS则更加注重整合、统一和优化整个生态系统。
- ArkTS的特性-扩展能力
- **基本语法 **
- 定义声明式UI、自定义组件、动态扩展UI元素;
- 提供ArkUI系统组件,提供组件事件、方法、属性;
- 共同构成 UI 开发主体
- **状态管理 **
- 组件状态、组件数据共享、应用数据共享、设备共享;
- **渲染控制 **
- 条件渲染、循环渲染、数据懒加载;
ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。
- 命令式UI- document.createElement(“div”)-
- 声明式UI
下图是关于ArtTS的一个整体的应用架构(官网)
info
总结:
- AktTS提供原有前端范畴内的一切TypeScript和JavaScript的类型及方法支持
- Next版本加了很多限制-要看迁移指南
- ArkTS采用声明式UI的方法来绘制页面,设置属性,绑定事件
ArkTS重点迁移说明
- 对象字面量不能用于类型声明
- 不支持in操作符
- 不支持解构赋值
- 不支持通过索引访问字段
有一种情况下,可以通过索引访问字段,即传入的参数类型为object, 但是传入时必须用class的类型传入,如下
@Entry
@Component
struct Index {
@State message: string = 'Hello World1';
test (obj: object) {
console.log(Object.keys(obj).map(item => `${
item}=${
obj[item]}`).toString())
}
aboutToAppear(): void {
let o = new TestObj()
this.test(o)
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
class TestObj {
a: number = 0
b: string = "123"
}
以上场景一般用作请求封装时,无法确定侦测传入参数的类型时使用
- 部分支持延展运算符
- 不支持bind/call/apply改变this指向
this始终指向调用者。谁调用这个方法,this指向谁
基础-组件结构
info
接下来,我们来解析我们的UI的结构
ArkTS通过装饰器 @Component
和 @Entry
装饰 struct
关键字声明的数据结构,构成一个自定义组件。
自定义组件中提供了一个 build
函数,开发者需在该函数内以链式调用的方式进行基本的 UI 描述,UI 描述的方法请参考 UI 描述规范。
- struct-自定义组件基于struct实现
要想实现一段UI的描述,必须使用struct关键字来声明- 注意不能有继承关系-组件名不能系统组件名重名
语法: struct 组件名 {}
@Component
struct Index {
}
@CustomDialog
struct Index2 {
}
info
struct关键字声明的UI描述-必须被@Component或者@CustomDialog修饰
- Component修饰符
Component装饰器只能修饰struct关键字声明的结构,被修饰后的struct具备组件的描述(渲染)能力
- build函数
用于定义组件的UI描述,一个struct结构必须实现build函数
@Component
struct MyComponent {
build() {
}
}
info
注意:
1.build函数是组件(Component)必须提供以及实现的一个函数,build函数可以没有内容,如果有的话,必须有且只有一个容器组件(可以放置子组件的组件)- 只有entry里面有限制- component里面没有限制
2.Component的组件build函数 可以放没有子组件的组件
-
常见容器组件- Flex-Column-Row-List-Grid-Panel
-
entry修饰符
entry将自定义组件定义为UI页面的入口,也就是我们原来前端常说的一个页面,最多可以使用entry装饰一个自定义组件(在一个ets文件中)-如下面的代码就是不被允许的
@Entry
@Component
struct Index {
build() {
}
}
@Entry
@Component
struct Index2 {
build() {
}
}
info
entry修饰的组件,最终会被注册,具体文件位置-main/resources/base/profile/main_pages.json
- 自动注册-新建组件时,采用新建Page的方式
- 手动注册-新建一个ets文件,自己在main_pages.json中手动添加路径
注意:
如果你手动删除了某一个带entry的组件,你需要手动去main_page中去删除该路径,否则编译会报错
- 组件复用
在很多情况下,由于业务的复杂度,我们经常会将一个大的业务拆成若干个组件,进行组装,这里我们非常灵活的复用组件,比如
info
- 我们可以把上图抽象成三个组件- Header- Main- Footer
代码
import {
MeiTuanFooter } from '../views/MeiTuan/MeiTuanFooter';
import {
MeiTuanHeader } from '../views/MeiTuan/MeiTuanHeader';
import {
MeiTuanMain } from '../views/MeiTuan/MeiTuanMain';
@Entry
@Component
struct MeiTuan {
@State message: string = 'Hello World';
build() {
Column() {
MeiTuanHeader() // 60
MeiTuanMain()
.layoutWeight(1)
.backgroundColor(Color.Green)
MeiTuanFooter() // 60
}.height('100%')
}
}
@Preview
@Component
struct MeiTuanHeader {
build() {
Row () {
Text("美团头部")
.width('100%')
.textAlign(TextAlign.Center)
}
.width('100%')
.height(60)
.backgroundColor(Color.Pink)
}
}
export {
MeiTuanHeader }
@Component
struct MeiTuanMain {
build() {
Row() {
Text("美团中部")
.fontColor(Color.Red)
}
.justifyContent(FlexAlign.Center)
.width('100%')
}
}
export {
MeiTuanMain }
@Component
struct MeiTuanFooter {
build() {
Row () {
Text("美团底部")
.fontColor(Color.White)
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height(60)
.backgroundColor(Color.Blue)
}
}
export {
MeiTuanFooter }
info
总结:
- 一个UI描述必须使用struct来声明,不能继承
- struct必须被Component或者CustomDialog修饰
- struct必须实现build方法,build方法可以没有元素,但是有的话有且只有一个可容纳子组件的容器组件(entry修饰的组件)
- entry修饰符表示该组件是页面级组件,一个文件中只允许修饰一个struct组件
- 采用分拆组件的形式可以有效解解耦我们的业务
基础-系统组件(ArkUI)
ArkUI: Ability Kit在UIAbility组件可以使用ArkUI提供的组件、事件、动效、状态管理等能力。
这里所指的Kit其实是Next版本中,鸿蒙将各个能力集进行了统一的分类
ArkUI将组件大概分为这么几类
- 基础组件
- 容器组件
- 媒体组件(只有一个Video)
- 绘制组件
- 画布组件
- 高级组件 额外新增
- 安全组件 额外新增
大家关心的地图功能在Next版本中以API形式呈现
基本组件使用
- Text 文本组件-(Span子组件 ImageSpan组件)
- Column 列组件,纵向排列,Flex布局主轴是Y (任意子组件)
- Row 行组件,横向排列,Flex布局主轴是X (任意子组件)
- Flex 以弹性方式布局子组件的容器组件。(存在二次布局,官方推荐有性能要求,使用Column和Row代替) (任意子组件)
- Button 按钮组件 (单子组件)
- TextInput 输入框组件 (无子组件)
- Image (无子组件)
- Button (单个子组件)
- List (仅支持ListItem子组件)
- Scroll (仅支持单个子组件)
- Stack(堆叠容器,子组件按照顺序依次入栈,后一个子组件覆盖前一个子组件)
- Grid(网格容器,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。仅支持GridItem组件)
- GridRow(栅格容器组件,仅可以和栅格子组件(GridCol)在栅格布局场景中使用。)
- GirdCol(栅格子组件,必须作为栅格容器组件(GridRow)的子组件使用。)
组件使用
info
- 使用组件采用 **组件名() **的语法
- 有构造参数采用 **组件名(参数)**的语法
- 组件里放置子组件采用 **组件名() { 子组件的语法 } **的链式语法
- 组件设置属性采用 **组件名().width().height() **的语法
- 组件又有属性又有子组件采用 **组件名(){ … 子组件 }.width().height() **的语法
基础布局
横向布局-采用Row
百分比说明: 鸿蒙的里面的百分比指的是相对当前父容器,并不是当前的手机屏幕
在写宽度高度时,直接写数字默认单位为vp虚拟像素,屏幕会进行适配。
Row组件默认情况下,子组件内容会垂直方向居中-** 内容超出不会换行**
@Entry
@Component
struct ComponentCase {
@State message: string = 'Hello World'
build() {
Column() {
// css 支持调整布局
Row({
space: 15 }) {
Column()
.width(100)
.height(200)
.backgroundColor(Color.Pink)
Column()
.width(100)
.height(200)
.backgroundColor(Color.Red)
Column()
.width(100)
.height(200)
.backgroundColor(Color.Blue)
}
.width('100%')
// .justifyContent(FlexAlign.Start)
.justifyContent(FlexAlign.Center)
// .justifyContent(FlexAlign.End)
// .justifyContent(FlexAlign.SpaceBetween)
// .justifyContent(FlexAlign.SpaceAround)
// .justifyContent(FlexAlign.SpaceEvenly)
}
.width('100%')
.height('100%')
}
}
纵向布局
@Entry
@Component
struct ComponentCase {
@State message: string = 'Hello World'
build() {
Column({
space: 10 }) {
// css 支持调整布局
Row({
space: 15 }) {
Column()
.width(100)
.height(200)
.backgroundColor(Color.Pink)
Column()
.width(100)
.height(200)
.backgroundColor(Color.Red)
Column()
.width(100)
.height(200)
.backgroundColor(Color.Blue)
}
.width('100%')
// .justifyContent(FlexAlign.Start)
.justifyContent(FlexAlign.Center)
Column({
space: 15 }) {
Column()
.width(200)
.height(100)
.backgroundColor(Color.Pink)
Column()
.width(200)
.height(100)
.backgroundColor(Color.Red)
Column()
.width(200)
.height(100)
.backgroundColor(Color.Blue)
}
.width('100%')
.justifyContent(FlexAlign.Center)
}
.width('100%')
.height('100%')
}
}
自定义组件应用
@Entry
@Component
struct Layout {
build() {
Column() {
RowCase()
ColumnCase()
}.height('100%').backgroundColor(Color.Grey)
}
}
@Component
struct RowCase {
build() {
Row() {
Column().height(150).width(100).backgroundColor(Color.Pink)
Column().height(150).width(100).backgroundColor(Color.Red)
Column().height(150).width(100).backgroundColor(Color.Blue)
}
.width('100%')
.alignItems(VerticalAlign.Top)
.justifyContent(FlexAlign.SpaceAround)
}
}
@Component
struct ColumnCase {
build() {
Column() {
Column().height(100).width(150).backgroundColor(Color.Pink)
Column().height(100).width(150).backgroundColor(Color.Red)
Column().height(100).width(150).backgroundColor(Color.Blue)
}.height(400).width('100%').justifyContent(FlexAlign.SpaceEvenly)
}
}
- 百度的小案例
@Entry
@Component
struct Baidu {
build() {
Column({
space: 20 }) {
Image("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png")
.width(160)
Row() {
TextInput()
.borderRadius({
topLeft: 6,
bottomLeft: 6
})
.height(40)
.layoutWeight(1)
.backgroundColor(Color.White)
.border({
color: "#c4c7ce",
width: 2
})
Button("百度一下")
.type(ButtonType.Normal)
.backgroundColor("#516aee")
.padding({
left: 10,
right: 10,
top: 6,
bottom: 6
})
.translate({
x: -2
})
.borderRadius({
topRight: 6,
bottomRight: 6
})
}
.padding({
left: 10,
right: 10
})
.width('100%')
}
.justifyContent(FlexAlign.Center)
.width('100%')
.height('100%')
}
}
warning
Row 和Column的布局方式成为线性布局- 不是横向排列就是纵向排列
- 线性布局中永远不会产生换行
- 均不支持出现滚动条
- 横向排列的垂直居中,总行排列的水平居中
- 主轴-排列方向的轴
- 侧轴-排列方向垂直的轴
堆叠布局
info
只要在Stack内部-后者永远会覆盖前者
@Entry
@Component
struct Baidu {
build() {
Column({
space: 12 }) {
// 图片
Row() {
Stack({
alignContent:Alignment.TopEnd}) {
Image('https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png')
.width(160)
Text('鸿蒙版')
.fontSize(12)
.offset({
x:-20,
y:30
})
}
}
.width('100%')
.justifyContent(FlexAlign.Center)
// 输入框+按钮
Row() {
TextInput()
.layoutWeight(1)
.border({
width: 2,
color: '#ccc'
})
.height(40)
.borderRadius({
topLeft: 4,
bottomLeft: 4
})
.backgroundColor('#fff')
Button('百度一下')
.type(ButtonType.Normal)
.translate({
x: -2
})
.borderRadius({
topRight: 4,
bottomRight: 4
})
}
}
.width('100%')
.height('100%')
.padding(16)
.justifyContent(FlexAlign.Center)
}
}
info
Stack的参数 可以设置子组件的排列方式-alignContent
- Top(顶部)
- TopStart(左上角)
- TopEnd(右上角)
- Start(左侧)
- End(右侧)
- Center(中间)
- Bottom(底部)
- BottomStart(左下角)
- BottomEnd(右下角)
@Entry
@Component
struct FontJump {
build() {
Row() {
Stack() {
Text('抖音')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.fontColor('#ff2d83b3')
.translate({
x:-2,
y:2
})
.zIndex(1)
Text('抖音')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.fontColor('#ffe31fa9')
.translate({
x:2,
y:-2
})
.zIndex(2)
Text('抖音')
.fontSize(50)
.fontWeight(FontWeight.Bold)
.fontColor('#ff030000')
.translate({
x:0,
y:0
})
.zIndex(3)
}
.width('100%')
}
.height('100%')
}
}
弹性布局
@Entry
@Component
struct ComponentCase {
@State message: string = 'Hello World'
build() {
Scroll() {
Row() {
Column() {
Flex({
direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceAround }) {
Column()
.width(100)
.height(200)
.backgroundColor(Color.Pink)
Column()
.width(100)
.height(200)
.backgroundColor(Color.Red)
Column()
.width(100)
.height(200)
.backgroundColor(Color.Blue)
}
.margin({
top: 200
})
}
.width('100%')
}
}
}
}
warning
Flex布局设置属性设置方向 是通过参数的,并非通过属性
- 属性?
- 参数?
网格布局
Grid布局
- 想要控制屏幕的分栏 分几列, 怎么分 特别像前端的栅格布局
- Row组件默认情况下,里面的元素的纵向是居中的
- Column组件默认横向是居中的
info
Grid组件下只能放置GridItem组件
Grid可以设置columnsTemplate和rowsTemplate
columnsTemplate是设置横向的分配,如果设置 1fr 1fr 表示,等分为两份, 如果设置1fr 2fr表示左边一份,右边两份, 在设置columnsTemplate不设置rowsTemplate的情况下,如果内容超出容器区域,会自动出现滚动条 columnsGap设置列和列之间的间距,rowsGap设置行和行之间的间距
@Entry
@Component
struct GridCase {
build() {
Grid() {
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
GridItemCase()
}
.width("100%")
.height("100%")
.columnsTemplate("1fr 1fr")
.columnsGap(10)
.rowsGap(10)
.padding(10)
}
}
@Component
struct GridItemCase {
build() {
GridItem() {
Row() {
Column() {
Text("内容")
}
.width('100%')
}
.height(200)
.borderRadius(4)
.backgroundColor(Color.Pink)
}
}
}
滚动条说明
在基本的布局组件 Column/Row/Flex/Stack中不论内容超出与否,皆不会出现滚动条
- 出现滚动条的组件
- Grid
- List(列表)
- Scroll(滚动条)
- Swiper(轮播)
- WaterFlow(瀑布流)
出现滚动条的前提条件是- 上述组件中的子组件的内容超出了父容器组件的宽度或者高度
- 使用最基本的Scroll组件出现一个滚动条
- 先实现基本的布局
@Entry
@Component
struct ScrollCase {
build(