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)案例:文档跳转

九、网络连接

十、数据持久化

相关推荐
独行soc2 小时前
2025年渗透测试面试题总结-某战队红队实习面经(附回答)(题目+回答)
linux·运维·服务器·学习·面试·职场和发展·渗透测试
奋斗者1号2 小时前
神经网络:节点、隐藏层与非线性学习
网络·神经网络·学习
真的想上岸啊3 小时前
学习Linux的第二天
学习
吃货界的硬件攻城狮3 小时前
【STM32 学习笔记】EXTI外部中断
笔记·stm32·学习
吃货界的硬件攻城狮3 小时前
【STM32 学习笔记 】OLED显示屏及Keil调试
笔记·stm32·学习
非凡ghost4 小时前
NoxLucky:个性化动态桌面,打造独一无二的手机体验
学习·智能手机·软件需求
海尔辛4 小时前
学习黑客 linux 提权
linux·网络·学习
烟雨柳成烟5 小时前
Qt学习Day0:Qt简介
开发语言·qt·学习
北极有牛6 小时前
cpp学习笔记2--class
c++·笔记·学习
IT小饕餮6 小时前
华为私有协议Hybrid
运维·服务器·华为