用户云卷云舒 发表于 2025-3-25 02:13:04

HarmonyOS学习(Day03-Day05):项目进度列表实战(首页)

#学习视频:bilibili蜗牛学苑#
【最新】全套鸿蒙开发HarmonyOS NEXT5.0实战教程
本篇文章重要为以下页面所用到的干系知识点
Day03

示例图
https://i-blog.csdnimg.cn/direct/39680c2d2a74496aaee1c0caa042e431.png
一、布局单元

在我们布局中,经常会采用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[] =

 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,)
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%')
}
} 结果如下:
https://i-blog.csdnimg.cn/direct/94408b8ad7a04cb79f090801515fde37.png
总结:
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
 })
}
} 结果:
https://i-blog.csdnimg.cn/direct/4482192db1a54bfbbf6932772a3ebbed.png
相对定位特性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)
}
} 结果:
https://i-blog.csdnimg.cn/direct/beb1eb46bd6d4cd28c72a1611f41252c.png
总结:
   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企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: HarmonyOS学习(Day03-Day05):项目进度列表实战(首页)