#学习视频:bilibili蜗牛学苑#
【最新】全套鸿蒙开发HarmonyOS NEXT5.0实战教程
本篇文章重要为以下页面所用到的干系知识点
Day03
示例图
一、布局单元
在我们布局中,经常会采用px来作为布局的一个尺寸参考单元,这个单元在浏览器中已经是布局的标准。在鸿蒙开发中,提出了一些新的单元用于布局。
物理像素:一样寻常用px来表示。
逻辑像素:在布局的时间,底层针对物理像素和屏幕的尺寸关系进行了转化的中心层。
分辨率:代表在屏幕上面到底布局了多少个像素点(发光点)。
- // 屏幕尺寸:1680px 分辨率:3560px
- div{
- width: 500px,
- height: 500px
- }
复制代码 这里写的的500px实际上参考3560px像素为布局,但是最终渲染出来的结果,转化为了1680px尺寸的比例。
鸿蒙开发中,要进行布局,我们采用官方提供的单元来实现
名称描述px屏幕物理像素单元。预览器默认1080px,假如你的盒子100px,默认参考1080px来布局vp屏幕密度干系像素,根据屏幕像素密度转换为屏幕物理像素,当数值不带单元时,默认单元vp。阐明:vp与px的比例与屏幕像素密度有关。以屏幕的实际巨细为参考布局(逻辑像素)fp字体像素,与vp类似实用屏幕密度厘革,随系统字体巨细设置厘革。lpx视窗逻辑像素单元,lpx单元为实际屏幕宽度与逻辑宽度(通过designWidth配置)的比值,designWidth默认值为720。当designWidth为720时,在实际宽度为1440物理像素的屏幕上,1lpx为2px巨细。 代码为:
- @Entry
- @Component
- struct Page01 {
- @State message: string = 'Hello World';
-
- build() {
- Column(){
- Text("文本")
- .fontSize("30fp") // 与不加单位时效果一样,但是当改变设备字体大小时也会跟着改变
- Row()
- .width("100vp") // 以屏幕的实际大小为参考布局,与不加单位时效果一样
- .height("100vp")
- .backgroundColor("#ccc")
- Row()
- .width("100lpx") // 1vp = 2lpx
- .height("100lpx")
- .backgroundColor("red")
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码 总结:
1、假如采用px作为单元,在鸿蒙中参考的物理像素作为布局参考尺寸,物理像素的值可能是动态厘革的,即放在不同手机上面,物理像素可能厘革。
2、vp作为鸿蒙开发中我们推荐的单元,采用当前装备的屏幕宽度来作为我们布局的参考,不管物理像素到底是多少。可以镌汰屏幕之间布局差别。不写单元时默认是vp。
3、fp一样寻常用于设置字体巨细,不写单元时默认会采用vp作为字体巨细单元。fp最大的特点是随着系统字体巨细的厘革而厘革。
4、lpx这个单元要进行换算。当计划稿为720时,在实际宽度为1440物理像素的屏幕上,1lpx为2px巨细。
Day04
二、Column和Row的布局
Column默认垂直方向为主轴,水平方向为侧轴。
Row默认水平方向为主轴,垂直方向为侧轴。
元素放在这两个容器中,子元素默认会在侧轴方向上面水平居中。
- @Entry
- @Component
- struct Page01 {
- @State message: string = 'Hello World';
-
- build() {
- // 以弹性布局为基础来理解
- Column(){
- Column(){
- Text("你好,小王")
- .fontSize(30)
- .fontWeight(FontWeight.Bold)
- .fontColor("#12175E")
- Text("测试代码")
- }
- .width("100%")
- .height("50%")
- .backgroundColor(Color.Gray)
- .alignItems(HorizontalAlign.Start) // 侧轴(水平方向)对齐方式
- .justifyContent(FlexAlign.Center) // 主轴(垂直方向)对齐方式
-
- Row(){
- Text("Row1")
- Text("Row2")
- }
- .width("100%")
- .height("50%")
- .backgroundColor(Color.Orange)
- .alignItems(VerticalAlign.Top) // 侧轴(水平方向)对齐方式
- .justifyContent(FlexAlign.SpaceBetween) // 主轴(垂直方向)对齐方式
- }
- }
- }
复制代码 在布局过程中这两个组件都可以用alignItems和justifyContent来调解子元素的布局方案。
关于颜色配置
在布局中,但凡遇到需要配置颜色,我们可以采用四个方案来计划
- // 设置颜色可以允许:英文单词、16进制、rgb、枚举
- .fontColor("red") // 英文单词
- .fontColor("#12175E") // 16进制
- .fontColor("rgb(233,456,12)") // rgb
- .fontColor(Color.orange) // 枚举
复制代码 可以根据计划师提供的原稿进行颜色吸取并用于布局页面。
三、Scroll滚动组件
在移动端开发过程中,我们都会遇到在水平方向或者垂直方向内容超出过后,默认无法检察的问题,这个需要借助官方提供Scroll组件来实现页面滚动。
支持水平方向滚动,也可以支持垂直方向滚动。
基础代码
- import { curves } from '@kit.ArkUI'
-
- @Entry
- @Component
- struct ScrollExample {
- // 滚动的控制器
- scroller: Scroller = new Scroller()
- private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-
- build() {
- Stack({ alignContent: Alignment.TopStart }) {
- Scroll(this.scroller) {
- Column() {
- ForEach(this.arr, (item: number) => {
- Text(item.toString())
- .width('90%')
- .height(150)
- .backgroundColor(0xFFFFFF)
- .borderRadius(15)
- .fontSize(16)
- .textAlign(TextAlign.Center)
- .margin({ top: 10 })
- }, (item: string) => item)
- }.width('100%')
- }
- .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
- .scrollBar(BarState.On) // 滚动条常驻显示
- .scrollBarColor(Color.Gray) // 滚动条颜色
- .scrollBarWidth(10) // 滚动条宽度
- .friction(0.6) // 设置摩擦系数,在穿戴设备,手机和平板一般不一样
- .edgeEffect(EdgeEffect.None) // 滚动到边缘位置的效果
- // 即将滚动的时候触发的事件
- .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
- console.info(xOffset + ' ' + yOffset)
- })
- // 滚动完成后触发的事件
- .onDidScroll(()=>{
- console.log("滚动完成")
- })
- // 滚动到边缘触发事件
- .onScrollEdge((side: Edge) => {
- console.info('To the edge')
- })
- // 滚动停止触发事件
- .onScrollStop(() => {
- console.info('Scroll Stop')
- })
-
- Button('scroll 150')
- .height('5%')
- .onClick(() => { // 点击后下滑指定距离150.0vp
- this.scroller.scrollBy(0, 150)
- })
- .margin({ top: 10, left: 20 })
- Button('scroll 100')
- .height('5%')
- .onClick(() => { // 点击后滑动到指定位置,即下滑100.0vp的距离
- const yOffset: number = this.scroller.currentOffset().yOffset;
- this.scroller.scrollTo({ xOffset: 0, yOffset: yOffset + 100 })
- })
- .margin({ top: 60, left: 20 })
- Button('scroll 100')
- .height('5%')
- .onClick(() => { // 点击后滑动到指定位置,即下滑100.0vp的距离,滑动过程配置有动画
- let curve = curves.interpolatingSpring(10, 1, 228, 30) //创建一个阶梯曲线
- const yOffset: number = this.scroller.currentOffset().yOffset;
- this.scroller.scrollTo({ xOffset: 0, yOffset: yOffset + 100, animation: { duration: 1000, curve: curve } })
- })
- .margin({ top: 110, left: 20 })
- Button('back top')
- .height('5%')
- .onClick(() => { // 点击后回到顶部
- this.scroller.scrollEdge(Edge.Top)
- })
- .margin({ top: 160, left: 20 })
- Button('next page')
- .height('5%')
- .onClick(() => { // 点击后滑到下一页
- this.scroller.scrollPage({ next: true })
- })
- .margin({ top: 210, left: 20 })
- }.width('100%').height('100%').backgroundColor(0xDCDCDC)
- }
- }
复制代码 常用属性
- .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
- .scrollBar(BarState.On) // 滚动条常驻显示
- .scrollBarColor(Color.Gray) // 滚动条颜色
- .scrollBarWidth(10) // 滚动条宽度
- .friction(0.6) // 设置摩擦系数,在穿戴设备,手机和平板一般不一样
- .edgeEffect(EdgeEffect.None) // 滚动到边缘位置的效果
复制代码 常用变乱
- // 即将滚动的时候触发的事件
- .onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
- console.info(xOffset + ' ' + yOffset)
- })
- // 滚动完成后触发的事件
- .onDidScroll(()=>{
- console.log("滚动完成")
- })
- // 滚动到边缘触发事件
- .onScrollEdge((side: Edge) => {
- console.info('To the edge')
- })
- // 滚动停止触发事件
- .onScrollStop(() => {
- console.info('Scroll Stop')
- })
复制代码 控制器的作用
- Scroll(this.scroller)
-
- Button('scroll 150')
- .height('5%')
- .onClick(() => { // 点击后下滑指定距离150.0vp
- this.scroller.scrollBy(0, 150)
- })
- .margin({ top: 10, left: 20 })
- Button('scroll 100')
- .height('5%')
- .onClick(() => { // 点击后滑动到指定位置,即下滑100.0vp的距离
- const yOffset: number = this.scroller.currentOffset().yOffset;
- this.scroller.scrollTo({ xOffset: 0, yOffset: yOffset + 100 })
- })
- .margin({ top: 60, left: 20 })
复制代码 scrollBy:在目前的滚动距离上面进行滚动距离累加
scrollTo:指定滚动到哪个位置
scrollEdge:滚动到容器边缘,不区分滚动轴方向
scrollPage:滚动到下一页或者上一页
Day05
四、this指向问题
面向对象开发的时间,会出现this利用
在进行变乱绑定的时间,也会调用this调用指向
在箭头函数中也会用到this,正确判断他的指向
结论:
1、this永远指向一个对象,不管在哪种场景下面
2、普通函数中的this,谁调用这个函数,默认this就指向谁
3、箭头函数默认没有this指向,假如箭头函数中有this出现,一定指向父级作用域
场景一:普通函数
- /**
- * 场景一:普通函数中的this
- */
- function show(){
- // this这个关键字,只是一个占位符
- console.log(this); // Window
- }
- show()
复制代码 场景二:面向对象
- /**
- * 场景二:Student只是类模板,真正的对象是new出来的
- */
- class Student{
- constructor(id,name){
- // 当new第一个实例stu1时,this指向stu1,当new第二个实例stu2时,this指向stu2
- this.id = id
- this.name = name
- this.message()
- }
- message(){
-
- }
- play(){
- this.message()
- }
- }
- const stu1 = new Student
- console.log(stu.id);
- const stu2 = new Student
复制代码 总结:
1、类模板中的this默认只是一个占位符,假如你没有通过类来new一个对象。实际上类中的this就没有意义。
2、当你执行new操作符的时间,通过类模板创建出一个对象,类中this代表new出来的对象。
3、类中函数和属性要相互调用,都必须通过this来进行调用。
场景三:变乱函数
- /**
- * 场景三:通过事件调用函数
- */
- const obtn = document.getElementById("btn")
- obtn.onclick = function(){
- // button节点
- console.log(this);
- }
复制代码 变乱函数中绑定了普通函数过后,内部的this默认指向变乱源对象。
场景四:箭头函数
- /**
- * 场景四:箭头函数中的this
- * 作用域:全局作用域、局部作用域(函数作用域)、eval作用域(忽略)、块级(不参与)
- */
- const user = {
- id: 1,
- name: "张三",
- play: ()=>{
- console.log(this); // Window
- },
- say: function(){
- return ()=>{
- console.log(this); // user
- }
- },
- sing: ()=>{
- return function(){
- console.log(this); // Window
- // 普通函数的this指向当前调用者,
- }
- }
- }
- user.play()
- user.say()()
- user.sing()()
- /**
- * user.sing()()相当于
- * const fun = user.sing()
- * fun()
- */
复制代码 改变this指向
- call: call可以传递多个参数,第一个是当前this环境,第二个往后是参数 call(this,1,2,3)
- apply: 可以传递两个参数,第一个是当前this环境,第二个往后是数组 apply(this,[1,2,3])
- bind: 参数跟call一样,传递多个。但是返回一个函数。const fun = bind(this,1,2,3) fun()
复制代码 五、Stack布局
概念
Stack层叠布局,可以实现子元素在指定的布局空间内,重叠在一起渲染。
类似于以前前端布局的绝对定位,默认情况下所有元素都叠在一起渲染。
基础代码
- @Entry
- @Component
- struct Page03_Stack {
- @State message: string = 'Hello World';
-
- build() {
- Column(){
- Stack(){
- Column(){
-
- }
- .width(300)
- .height(300)
- .backgroundColor(Color.Brown)
- Column(){
-
- }
- .width(200)
- .height(200)
- .backgroundColor(Color.Blue)
- Column(){
-
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Orange)
- }
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码 结果如下:
总结:
1、放在Stack容器里的元素,默认会产生重叠。
2、所有子元素在重叠的时间,默认居中排列
位置的设置
在Stack容器加载的时间,可以设置参数。
Stack({alignContent:Alignment.TopStart})
alignContent:就是代表默认的子元素排列位置
Alignment:官方提供位置罗列数据,左上、右上、左下、右下、居中、上下左右的位置来布局
zIndex控制层级
zIndex控制层级类似于绝对定位里面层级控制,值越大层级越高
- Column(){}
- .width(200)
- .height(200)
- .backgroundColor(Color.Blue)
- .zIndex(999)
复制代码 zIndex是一个属性,用在子元素身上。
六、相对布局 (RelativeContainer)
概念
RelativeContainer出现为了让容器布局更加多样化,尤其是多个组件层叠,多个组件之间位置调解。在鸿蒙中RelativeContainer容器包罗了相对定位和绝对定位概念。重要用于控制页面中某一区域,以及这个区域内部的元素排列规则。
指定一个容器作为RelativeContainer,里面的元素在排列过程中,参考以下的布局规范:
容器内子元素区分水平方向布局和垂直方向布局。
水平方向:left、middle、right,对应容器的位置为:start、center、end
垂直方向:top、center、bottom,对应容器的位置为:top、center、bottom
相对定位特性1
在RelativeContainer容器中设置子元素,默认情况没有设置子元素的相对偏移,默认所有元素层叠在一起,对齐容器的左上角
代码:
- @Entry
- @Component
- struct Page04_RelativeContainer {
- @State message: string = 'Hello World';
-
- build() {
- RelativeContainer() {
- Column(){
- Text("box1")
- }
- .width(300)
- .height(300)
- .backgroundColor(Color.Brown)
- Column(){
-
- }
- .width(200)
- .height(200)
- .backgroundColor(Color.Blue)
- Column(){
-
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Orange)
-
- }
- .height('50%')
- .width('100%')
- .border({
- width: 1,
- color: Color.Pink
- })
- }
- }
复制代码 结果:
相对定位特性2
在RelativeContainer中子元素可以设置偏移位置。
难点:子元素可以以RelativeContainer作为偏移参考,也可以以其他子元素作为偏移参考。
所有子元素以RelativeContainer作为定位的偏移参考,代码如下:
- @Entry
- @Component
- struct Page04_RelativeContainer {
- @State message: string = 'Hello World';
-
- build() {
- Column(){
- RelativeContainer() {
- Column(){
- Text("box1")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Brown)
-
- .alignRules({
- // left:子元素水平方向参考线,anchor:锚点(参考元素),align:锚点水平位置参考线
- // top:子元素垂直方向参考线,anchor:锚点(参考元素),align:锚点垂直位置参考线
- /** left:{anchor:"__container__",align:HorizontalAlign.Start}
- * 表示:子容器的最左边的边参考父容器,与父容器的最左边的边对齐
- */
- left:{anchor:"__container__",align:HorizontalAlign.Start},
- top:{anchor:"__container__",align:VerticalAlign.Top}
- })
- Column(){
- Text("box2")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Blue)
- .alignRules({
- right: {anchor:"__container__",align:HorizontalAlign.End},
- top:{anchor:"__container__",align:VerticalAlign.Top}
- })
- Column(){
- Text("box3")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Orange)
- .alignRules({
- middle:{anchor:"__container__",align:HorizontalAlign.Center},
- center:{anchor:"__container__",align:VerticalAlign.Center}
- })
- Column(){
- Text("box4")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Brown)
- .alignRules({
- bottom:{anchor:"__container__",align:VerticalAlign.Bottom},
- left:{anchor:"__container__",align:HorizontalAlign.Start}
- })
- Column(){
- Text("box5")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Yellow)
- .alignRules({
- right:{anchor:"__container__",align:HorizontalAlign.End},
- bottom:{anchor:"__container__",align:VerticalAlign.Bottom}
- })
- }
- .height(300)
- .width(300)
- .border({
- width: 1,
- color: Color.Red
- })
- }
- .width("100%")
- .height("100%")
- .justifyContent(FlexAlign.Center)
- .alignItems(HorizontalAlign.Center)
- }
- }
复制代码 结果:
总结:
1、alignRules放在子元素身上,代表子元素设置相对位置,需要提供参考元素(锚点),以及子元素的参考线,以及对齐元素的参考线
2、水平方向参考线有三个,垂直方向参考线有三个
3、参考元素默认 __container__ 代表父级容器,后面可换成你指定的其他容器
可以利用offset来设置子元素定位好了之后,位置细节调解
- .alignRules({
- right:{anchor:"__container__",align:HorizontalAlign.End},
- bottom:{anchor:"__container__",align:VerticalAlign.Bottom}
- })
- .offset({
- x: -30,
- y: -100
- })
复制代码 x:正数代表水平靠右移动,反之相反。
y:正数代表垂直向下移动,反之相反。
相对定位特性3
子元素可以相对于其他子元素进行位置控制,之前的案例都是相对于父元素来进行位置控制,其实可以以子元素为参考来进行位置设置。
- @Entry
- @Component
- struct Page04_RelativeContainer {
- @State message: string = 'Hello World';
-
- build() {
- Column(){
- RelativeContainer() {
- Column(){
- Text("box1")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Brown)
- .id("row1")
- Column(){
- Text("box2")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Blue)
- .id("row2")
- .alignRules({
- right: {anchor:"__container__",align:HorizontalAlign.End},
- top:{anchor:"__container__",align:VerticalAlign.Top}
- })
- Column(){
- Text("box3")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Orange)
- .id("row3")
- // 以box1作为锚点
- /*.alignRules({
- left:{anchor:"row1",align:HorizontalAlign.End},
- top:{anchor:"row1",align:VerticalAlign.Bottom}
- })*/
- // 以box2作为锚点
- .alignRules({
- right:{anchor:"row2",align:HorizontalAlign.Start},
- top:{anchor:"row2",align:VerticalAlign.Bottom}
- })
- Column(){
- Text("box4")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Brown)
- .id("row4")
- .alignRules({
- top:{anchor:"row3",align:VerticalAlign.Bottom},
- right:{anchor:"row3",align:HorizontalAlign.Start}
- })
- Column(){
- Text("box5")
- }
- .width(100)
- .height(100)
- .backgroundColor(Color.Yellow)
- .id("row5")
- .alignRules({
- left:{anchor:"row3",align:HorizontalAlign.End},
- top:{anchor:"row3",align:VerticalAlign.Bottom}
- })
- }
- .height(300)
- .width(300)
- .border({
- width: 1,
- color: Color.Red
- })
- }
- .width("100%")
- .height("100%")
- .justifyContent(FlexAlign.Center)
- .alignItems(HorizontalAlign.Center)
- }
- }
复制代码 总结:
1、子元素之间可以相互作为移动位置的参考,anchor设置为对应子元素id编号
2、每次移动一个子元素时,参考的那个子元素要固定下来,否则参考子元素位置发生厘革,其他元素会受到影响
相对定位特性4
设置一个元素在父容器中水平垂直居中显示。
实现方案如下:
方案一:
- .alignRules({
- middle:{anchor:"__container__",align:HorizontalAlign.Center},
- center:{anchor:"__container__",align:VerticalAlign.Center}
- })
复制代码 总结:
1、子元素水平方向的中心线和父元素水平方向的居中位置重叠,水平方向居中。
2、子元素垂直方向的中心线和父元素垂直方向的居中位置重叠,垂直方向居中。
方案二(类似于前端中用定位实现元素水平垂直居中):
- .alignRules({
- left:{anchor:"__container__",align:HorizontalAlign.Start},
- right:{anchor:"__container__",align:HorizontalAlign.End},
- top:{anchor:"__container__",align:VerticalAlign.Top},
- bottom:{anchor:"__container__",align:VerticalAlign.Bottom}
- })
复制代码 总结:
1、设置水平方向居中显示,单独设置left、right,让容器自己去移动元素在水平方向居中
1、设置垂直方向居中显示,单独设置top、bottom,让容器自己去移动元素在垂直方向居中
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |