0基础学习鸿蒙开发-HarmonyOS4

一、初识

1. 开发工具

官网 开发-HarmonyOS NEXT鸿蒙应用开发平台-华为开发者联盟

2. ArkTS

二、TypeScript 基本语法

1.变量声明

2. 条件控制

注意

在TypeScrips中·

空字符串·数字0、null、undefined 都坡认为是false

其它值则为true

TypeScript 复制代码
if (num) {
  // num 非空执行
}

3. 循环迭代

4. 函数

5. 类和接口

6. 模块化开发

三、快速入门

1. 创建项目

2. 结构信息

路由配置地址:

3. 入门案例

TypeScript 复制代码
@Entry
@Component
struct Index { //自定义组件  --可以复用的UI单元
  @State message: string = 'Hello World';

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .fontColor('red')
          .onClick(() => {
            this.message = '你好世界'
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

四、ArkUI 基础组件

1. Image 组件

2. Text 组件

3. TextInput 文本输框

  • 数值转字符串:
复制代码
        数值.toFixed(0) --保留0位小数
  • 字符串转数值:
复制代码
        parseInt(字符串)

4. Button 按钮

5. Slider 滑块

6. Column和Row

1) 主轴

2)交叉轴

7. 案例源码

TypeScript 复制代码
@Entry
@Component
struct Index { //自定义组件  --可以复用的UI单元
  @State message: string = 'HarmonyOS';
  @State imgWidth:number = 250;
  build() {
    Column() {
      //   图片
      Row() {
        Image($rawfile('HarmonyOS.jpg'))
          .width(this.imgWidth)  //默认单位 vp(虚拟像素)
          .interpolation(ImageInterpolation.High) //处理图片边缘锯齿
          .borderRadius(20) //边框弧度
      }
      .width('100%')
      .height(400)
      .justifyContent(FlexAlign.Center)

      //   文本提示
      Row() {
        Text($r('app.string.width_label'))
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
        // .toFixed(0) 数值转字符串 保留0位小数
        TextInput({placeholder:'请输入宽度',text:this.imgWidth.toFixed(0)})
          .width(250)
          .type(InputType.Number)
          .onChange((value:string) => {
            // console.log(value)
            // parseInt 字符转数值
            this.imgWidth = parseInt(value)
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceBetween)
      .padding({left:15,right:15})
      // 分割线
      Divider()
        .width('91%')
        .color('red')

      //   按钮
      Row(){
        Button('缩小')
          .width(80)
          .fontSize(20)
          .onClick(() => {
            if (this.imgWidth >= 10) {
              this.imgWidth -= 10
            }
          })

        Button('放大')
          .width(80)
          .fontSize(20)
          .type(ButtonType.Normal)
          .onClick(() => {
            if (this.imgWidth <= 300) {
              this.imgWidth += 10
            }
          })
      }
      .width('100%')
      .justifyContent(FlexAlign.SpaceEvenly)
      .margin({top:20,bottom:20})

      //   滑块
      Slider({
        min:10,
        max:310,
        value:this.imgWidth,
        step:10,
        style: SliderStyle.OutSet
      })
        .width('90%')
        .borderColor('#36D')
        .trackThickness(7)
        .showTips(true)
        .onChange((value)=> {
          this.imgWidth = value
        })



    }
    .width('100%')
    .height('100%')
  }
}

8. 渲染控制

1) ForEach

2) if-else

9. List 列表

复制代码
List({space:6}){
  ForEach(this.tasks,(item:Task) => {
    ListItem() {
      Row(){
        Text(item.name)
          .fontSize(20)
          .textAlign(TextAlign.Start)
          .padding({left:10})
        Checkbox()
          .select(item.finished)
          .onChange((val)=> {
            // 更新当前任务状态
            item.finished = val
            // 更新已完成任务数量
            // this.finishTask = this.tasks.filter(i=> i.finished).length
            this.handleTaskChange()
          })
      }
      .card()
      .justifyContent(FlexAlign.SpaceBetween)
    }
  })
}
.width('100%')
.layoutWeight(1) //剩下的高度全是我的
.alignListItem(ListItemAlign.Center) //列表居中
TypeScript 复制代码
class Item {
  name: string
  image: ResourceStr
  price: number
  discount: number

  constructor(name:string, image:ResourceStr, price: number , discount:number = 0) {
    this.name = name
    this.image = image
    this.price = price
    this.discount = discount
  }
}

@Entry
@Component
struct ItemPage {
    //商品数据
  private  items:Array<Item> = [
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999,500),
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999),
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999),
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999),
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999),
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999),
    new Item('华为mate60',$rawfile('HarmonyOS.jpg'),6999),
  ]

  build() {
    Column({space:8}) {
      Row(){
        Text('商品列表')
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
      .margin({bottom:20})
      .height(30)

      List({space:8}){
        ForEach(this.items,(item:Item) => {
          ListItem(){
            Row() {
              Column(){
                Image(item.image)
                  .width(100)
              }
              Column(){
                Row(){
                  Text(item.name)
                }
                Column(){
                  if (item.discount) {
                    Row(){
                      Text('原价:')
                      Text(item.price.toFixed(0))
                        .decoration({type: TextDecorationType.LineThrough})
                    }
                    Row(){
                      Text('价格:')
                      Text((item.price - item.discount).toFixed(0))
                    }
                    Row(){
                      Text('折扣:')
                      Text(item.discount.toFixed(0))
                    }
                  }else {
                    Row(){
                      Text('价格:')
                      Text(item.price.toFixed(0))
                    }
                  }
                }
              }
            }
            .margin({left:10,right:10})
          }
        })
      }
      .width('100%')
      .layoutWeight(1) 
      
    }
  }
}

10. 自定义组件

Blank: 将容器剩余空间全部占满

五、状态管理

1. states 装饰器

2. 案例:多任务统计

进度条组件

复制代码
Progress({  
  value:this.finishTask,  //当前值
  total:this.totalTask,   //总值
  type:ProgressType.Ring  //样式 --环形
})

堆叠容器:
Stack() {

Progress(...) --盒子1

Row() {...} --盒子2

}

复制代码
    

多选框 :

Checkbox(options?: CheckboxOptions)

复制代码
Checkbox()
  .select(item.finished)
  .onChange((val)=> {
    // 更新当前任务状态
    item.finished = val
    // 更新已完成任务数量
    // this.finishTask = this.tasks.filter(i=> i.finished).length
    this.handleTaskChange()
  })

List 列表项 ListItem 划出样式

swipeAction()

swipeAction({end:this.DeleteBnt(idnex)})

复制代码
@Builder DeleteBnt(index:number) {
Button('删除')
.backgroundColor('red')
.onClick( () =\> {
this.tasks.splice(index,1)
this.handleTaskChange()
})
}

{ 右边划出:划出之后的内容 }

案例源码

TypeScript 复制代码
// 案例:多任务统计
import { it } from '@ohos/hypium'
@Observed
class Task{
  static id:number = 1 //任务id
  name:string = `任务${Task.id++}` //名称
  finished:boolean = false  //是否完成
}

// 统一卡片样式
@Styles function card(){
  .width('95%')
  .padding(20)
  .backgroundColor(Color.White)
  .borderRadius(15)
  .shadow({radius:6,color:'#1F000000',offsetX:2,offsetY:4})
}

// 任务完成样式
@Extend(Text) function finishedTask() {
  .decoration({type:TextDecorationType.LineThrough})
  .fontColor('#B1B2B1')
}


@Entry
@Component
struct PropPage {
  // 总任务数量
  @State totalTask: number = 0
  // 已完成任务数量
  @State finishTask:number = 0



  build() {
    Column({space:10}) {
      // 1. 任务进度
      TaskStatistics({finishTask:this.finishTask,totalTask:this.totalTask})

      // 2.任务列表
      TaskList({finishTask: $finishTask,totalTask:$totalTask})
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F1F2F3')
  }


}


@Component
struct TaskStatistics {
  @Prop finishTask:number
  @Prop totalTask:number

  build() {
    Row(){
      Text('任务进度')
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
      // 堆叠容器
      Stack() {
        Progress({  // 进度条
          value:this.finishTask,
          total:this.totalTask,
          type:ProgressType.Ring
        })
        Row() {
          Text(this.finishTask.toString())
            .fontSize(24)
            .fontColor('#36D')
          Text('/'+this.totalTask.toString())
            .fontSize(24)
        }
      }
    }
    .card()
    .margin({top:20,bottom:10})
    .justifyContent(FlexAlign.SpaceEvenly)
  }
}

@Component
struct TaskItem {
  @ObjectLink item:Task;
  onTaskChange: ()=> void =() => {}
  build() {
    Row() {
      if(this.item.finished){
        Text(this.item.name)
          .finishedTask()
      }else{
        Text(this.item.name)
          .fontSize(20)
          .textAlign(TextAlign.Start)
          .padding({ left: 10 })
      }
      Checkbox()
        .select(this.item.finished)
        .onChange((val) => {
          // 更新当前任务状态
          this.item.finished = val
          // 更新已完成任务数量
          // this.finishTask = this.tasks.filter(i=> i.finished).length
          this.onTaskChange()
        })
    }
    .card()
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

@Component
struct TaskList {
  // 任务数组
  @State tasks: Task[] = []

  @Link totalTask: number
  // 已完成任务数量
  @Link finishTask:number

  @Builder DeleteBnt(index:number) {
    Button('删除')
      .backgroundColor('red')
      .onClick( () => {
        this.tasks.splice(index,1)
        this.handleTaskChange()
      })
  }

  handleTaskChange() {
    // 更新任务总数
    this.totalTask = this.tasks.length
    // 更新已完成任务数量
    this.finishTask = this.tasks.filter(i=> i.finished).length
  }

  build() {
    Column() {
      Button('新增任务')
        .width(200)
        .onClick(() => {
          // 新增任务
          this.tasks.push(new Task())
          // 更新任务总数
          // this.totalTask = this.tasks.length
          this.handleTaskChange()
        })

      // 3.任务列表
      List({ space: 6 }) {
        ForEach(this.tasks, (item: Task, idnex: number) => {
          ListItem() {
            TaskItem({item:item,onTaskChange: this.handleTaskChange.bind(this)})
          }
          .swipeAction({ end: this.DeleteBnt(idnex) })
        })
      }
      .width('100%')
      .layoutWeight(1)
      .alignListItem(ListItemAlign.Center) //列表居中
    }
  }

}

2)@Provide @Consume

@Provide****父组件 传递

@Consume****子组件 获取

不需要传参

六、页面路由

1. 示例

页面路由配置地址

创建文件为页面是则自动添加路径

2. 案例

案例源码

TypeScript 复制代码
import router from '@ohos.router'

class RouterInfo {
//   页面路径
  url: string
//   页面标题
  title: string
  constructor(url:string, title:string) {
    this.url = url
    this.title = title
  }
}

@Entry
@Component
struct Index {
  @State message: string = '页面列表'

  private routers: RouterInfo[] = [
    new RouterInfo('pages/itemPage','商品列表'),
    new RouterInfo('pages/PropPage','多任务'),
    new RouterInfo('pages/ImagePage','图片查看')
  ]

  @Builder
  RouterItem(r: RouterInfo, i: number) {
    Row(){
      Text(i.toString()).fontColor(Color.White)
      Text(r.title).fontColor(Color.White)
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .backgroundColor('#36D')
    .padding({left:20,right:20})
    .borderRadius(20)
    .width('100%')
    .height(50)
    .onClick(() => {
    //   router 跳转
      router.pushUrl(
        {
          url:r.url,
          params:{
            id:i
          }
        },
        router.RouterMode.Single,  //页面跳转模式
        err => {
          if (err) {
            console.log(`跳转失败,errCode:${err.code} errMsg:${err.message}`)
          }
        }
      )

    })
  }

  build() {
    Column(){
      Text(this.message)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .height(50)
        .fontColor(Color.Pink)

      List({space:8}) {
        ForEach(this.routers,(router:RouterInfo,index:number)=>{
          ListItem() {
            this.RouterItem(router,(index+1))
          }
        })
      }
      .layoutWeight(1)
    }

  }
}
TypeScript 复制代码
import router from "@ohos.router"

// 定义组件
@Component
export  struct Header {
  private title:ResourceStr = '列表'
  @State params:object = router.getParams() //拿到传参
  build() {
    Row(){
      Text('<-')
        .onClick(()=> {
          router.showAlertBeforeBackPage({
            message:'返回页面'
          })  //返回前提示
          router.back() //返回路由

        })
      if(this.params) {
        Text(`${this.params}, ${this.title}`)
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
      }else {
        Text(this.title) // 只显示默认标题
          .fontSize(18)
          .fontWeight(FontWeight.Bold)
      }


    }
    .width('100%')
    .height(30)
  }
}

3. 总结

七、动画

1. 属性动画和显式动画

1)属性动画

案例:

Image(this.src)
.position({x:this.fishX-20,y:this.fishY-20}) // 定义初始位置
.rotate({angle:this.angle,centerX:"50%",centerY:'50%'}) // 定义动画运动样式
.width(40)
.height(40)
// 添加属性动画
.animation({duration:500}) //动画播放参数{}

//修改属性实现动画

复制代码
Button("v").backgroundColor('#20101010')
  .onClick(()=> {
    this.fishY += 20
  })
TypeScript 复制代码
import { Header } from '../components/CommonComponents'
import router from '@ohos.router';

@Entry
@Component
struct AnimationPage {
  @State fishX: number = 200
  @State fishY: number = 180
  // 小鱼角度
  @State angle:number = 0
  // 小鱼图片
  @State src: Resource = $r('app.media.startIcon')
  // 是否开始游戏
  @State isBegin: boolean = false;

  build() {
    Row() {
      // Header({title:"小鱼动画"})

      Stack() {  //堆叠容器
        Button('返回')
          .position({x:0,y:0})
          .backgroundColor(Color.Pink)
          .onClick(()=> {
            router.back()
          })
          .margin({top:0})
          .zIndex(1)


        if(!this.isBegin) {
          Button('开始游戏')
            .onClick(() => {
                this.isBegin = true
            })
            .margin({left:250})
        }else{
          // 小鱼图片
          Image(this.src)
            .position({x:this.fishX-20,y:this.fishY-20})
            .rotate({angle:this.angle,centerX:"50%",centerY:'50%'})
            .width(40)
            .height(40)
        //   添加属性动画
            .animation({duration:500})

        //   操作按钮
          Row(){
            Button('<').backgroundColor('#20101010')
              .onClick(()=> {
                this.fishX -= 20
              })
            Column({space:40}) {
              Button('^').backgroundColor('#20101010')
                .onClick(()=> {
                  this.fishY -= 20
                })
              Button("v").backgroundColor('#20101010')
                .onClick(()=> {
                  this.fishY += 20
                })
            }
            Button('>').backgroundColor('#20101010')
              .onClick(()=> {
                this.fishX += 20
              })
          }
          .height(240)
          .width(240)
        }

      }

    }
    .height('100%')
    .width('100%')
  }
}

2)显式动画 *

复制代码
Image(this.src)
  .position({x:this.fishX-20,y:this.fishY-20})
  .rotate({angle:this.angle,centerX:"50%",centerY:'50%'})
  .width(40)
  .height(40)
复制代码
Button('<').backgroundColor('#20101010')
  .onClick(()=> {
    // this.fishX -= 20
    animateTo({duration:500},()=>{
      this.fishX -= 20
    })
  })

2. 组件转场动画

3. 实现摇杆功能

八、Stage 模型

1. 应用配置组件

23-Stage模型-应用配置文件_哔哩哔哩_bilibili

2. UIAbility 生命周期

3. 页面组件生命周期

4. UIAbility的启动模式

修改模式

1)案例:文档跳转

九、网络连接

十、数据持久化

相关推荐
AA陈超8 小时前
UE5笔记:OnComponentBeginOverlap
c++·笔记·学习·ue5·虚幻引擎
培风图楠8 小时前
Java个人学习笔记
java·笔记·学习
q***d1739 小时前
后端缓存技术学习资源,Redis+Memcached
redis·学习·缓存
二流小码农9 小时前
鸿蒙开发:支持自定义组件的跑马灯
android·ios·harmonyos
因为奋斗超太帅啦10 小时前
Git分布式版本控制工具学习笔记(一)——git本地仓库的基本使用
笔记·git·学习
Jeled10 小时前
RecyclerView ViewHolder 复用机制详解(含常见错乱问题与优化方案)
android·学习·面试·kotlin
可可苏饼干11 小时前
LVS服务器
linux·运维·笔记·学习·lvs
2013编程爱好者11 小时前
【HUAWEI】HUAWEI Mate 70 Air详解
华为·harmonyos
四谎真好看11 小时前
Java 黑马程序员学习笔记(进阶篇27)
java·开发语言·笔记·学习·学习笔记
爱笑的眼睛1115 小时前
HarmonyOS USB设备管理深度探索:从基础到高级应用
华为·harmonyos