HarmonyOS4.0之ArkTs学习笔记

HarmonyOS4.0 ArkTs 学习笔记

前言

ArkTs组件的简单用法,在此记录,欢迎大家来指正。

1.ArkTS工程目录结构(Stage模型)

在这里插入图片描述

  • AppScope > app.json5:应用的全局配置信息。
  • entry:HarmonyOS工程模块,编译构建生成一个HAP包。
    • src > main > ets:用于存放ArkTS源码。
    • src > main > ets > entryability:应用/服务的入口。
    • src > main > ets > pages:应用/服务包含的页面。
    • src > main > resources:用于存放应用/服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件,详见资源分类与访问。
    • src > main > module.json5:Stage模型模块配置文件。主要包含HAP包的配置信息、应用/服务在具体设备上的配置信息以及应用/服务的全局配置信息。具体的配置文件说明,详见module.json5配置文件。
    • build-profile.json5:当前的模块信息、编译信息配置项,包括buildOption、targets配置等。其中targets中可配置当前运行环境,默认为HarmonyOS。
    • hvigorfile.ts:模块级编译构建任务脚本,开发者可以自定义相关任务和代码实现。
  • oh_modules:用于存放三方库依赖信息。关于原npm工程适配ohpm操作,请参考历史工程迁移。
  • build-profile.json5:应用级配置信息,包括签名、产品配置等。
  • hvigorfile.ts:应用级编译构建任务脚本。

2.ArkUI组件

1. Image组件

语法:Image(src: string | Resource | media.PixelMap)

  • 本地资源

    创建文件夹,将本地图片放入ets文件夹下的任意位置。

    Image组件引入本地图片路径,即可显示图片(根目录为ets文件夹)。

    Image('images/view.jpg')
    .width(200)
    
  • 网络资源

    引入网络图片需申请权限ohos.permission.INTERNET,具体申请方式请参考权限申请声明。此时,Image组件的src参数为网络图片的链接。

    Image('https://www.example.com/example.JPG') // 实际使用时请替换为真实地址
    
  • Resource资源

    使用资源格式可以跨包/跨模块引入图片,resources文件夹下的图片都可以通过$r资源接口读取到并转换到Resource格式。

    Image($r('app.media.icon'))
    
  • 还可以将图片放在rawfile文件夹下

    Image($rawfile('snap'))
    

2. Text组件

Text组件有两种声明方式:

  • string格式,直接填写文本内容

    Text('图片宽度')
    
  • Resource格式,读取本地资源文件

    Text($R('app.string.width_label'))
    

3. TextInput组件

格式:TextInput({placeholder?:ResourceStr,text?:ResourceStr})

TextInput({placeholder:'请输入内容',text:'组件'})

4. Button组件

​ 格式:Button(lable?:ResourceStr)

​ 类型为文字型按钮和自定义按钮

  • 文字型按钮

    Button('点击')
    
  • 自定义按钮(在Button内嵌套其他组件)

    Button(){
        Image($r('app.media.search'))
        .width(20)
        .margin(10)
    }
    

5. Slider组件

格式:Silder({

​ min:0,

​ max:100,

​ value:30,

​ step:10,

​ style:SliderStyle.OutSet,

​ direction:Axis.Horizontal,

​ reverse:false

})

6. Column和Row组件

  • Columnw容器
    • 从上到下为主轴,从左到右为交叉轴
    • 属性方法名:
      • justifyContent:设置子元素在主轴方向的对齐格式(参数为FlexAlign)
      • alignItems:设置子元素在交叉轴方向的对齐格式(Row->VerticalAlign,Column->HorizontaAlign)

在这里插入图片描述

在这里插入图片描述

3. 循环控制

  • ForEach和if else

    • ForEach语法:ForEach(item,(item)=>{},唯一标识)

    在这里插入图片描述

    • if(){}else{} 在此不做叙述

4. List

/**
 * 1.List容器不可以嵌套其他容器,只能嵌套ListItem。
 * 2.ListItem只能有一个根容器
 * 3.List容器可以支持滑动效果
 * 4.List更改布局方向,横向V。纵向H
 */

5. 自定义组件

  • 自定义组件

    • Header.ets页面(子组件)

      //自定义组件
      @Component//组件声明
      export struct ShopTitle{
        private title:ResourceStr//接收的参数
        build(){
          Row() {
            Text(this.title)
              .width('100%')
              .fontSize(50)
          }
        }
      }
      
    • index.ets(父组件)

      //导入自定义组件
      import { ShopTitle } from '../components/Header'
      @Entry
      @Component
      struct ItemPage {
        build() {
      
          Column() {
            /**
             * 1. 自定义组件调用-----自定义组件------
             * 2. 在调用的组件上设置样式
             */
            ShopTitle({ title: '商品列表' })
              .padding(10)
              .backgroundColor('gray')
          }
        }
      }
      
  • 自定义构建函数(全局/局部)

    /**
     * 自定义构建函数----(全局/局部)
     * 全局(写在组件外面的):
     *  定义全局构建函数时要加上function标识,并且调用的时候直接使用全局构建函数的名字即可
     * 局部(写在build()函数里面的):
     *  定义局部构建函数时不需要生命function标识,并且调用局部构建函数的时候需要使用this.
     *
     */
    

    示例代码:

    //全局类
    class Items {
      ImageName: ResourceStr
      ShopName: string
      ShopPrice: number
      ShopPreferential: number
    
      constructor(ImageName: ResourceStr, ShopName: string, ShopPrice: number, ShopPreferential: number) {
        console.log('构造函数')
        this.ImageName = ImageName
        this.ShopName = ShopName
        this.ShopPrice = ShopPrice
        this.ShopPreferential = ShopPreferential
      }
    }
    
    //导入自定义组件
    import { ShopTitle } from '../components/Header'
    
    /**
     * 自定义构建函数
     */
    @Builder function ShopList(Item: Items) {
      Row() {
        Image(Item.ImageName)
          .width(70)
          .height(70)
          .margin(20)
        Column() {
          if (Item.ShopPreferential) {
            Text(Item.ShopName)
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
            Text('原价:¥' + Item.ShopPrice)
              .fontSize(15)
              .fontColor('gray')
              .decoration({ type: TextDecorationType.LineThrough, color: 'black' })
            Text('折扣价:¥' + (Item.ShopPrice - Item.ShopPreferential))
              .fontSize(18)
              .fontColor('red')
            Text('补贴:¥' + Item.ShopPreferential)
              .fontSize(18)
              .fontColor('red')
          } else {
            Text(Item.ShopName)
              .fontSize(20)
              .fontWeight(FontWeight.Bold)
            Text('¥' + Item.ShopPrice)
              .fontSize(18)
              .fontColor('red')
          }
        }
        .height('100%')
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Start)
      }
      .height(100)
      .width('95%')
      .backgroundColor('#fff')
      .margin({
        top: 20,
        left: 10,
        right: 10,
      })
      .borderRadius(15)
    }
    
    
    @Entry
    @Component
    struct ItemPage {
      //商品数据
      private items: Array<Items> = [
        new Items($r('app.media.icon'), '商品1', 3699, 8),
        new Items($r('app.media.icon'), '商品2', 3799, 0), '商品3', 3899, '商品4', 3999, '商品5', 4699, '商品6', '商品7', '商品8', 0)
      ]
    
      build() {
    
        Column() {
          /**
           * 自定义组件调用-------------------------自定义组件
           */
          ShopTitle({ title: '商品列表' })
            .padding(10)
            .backgroundColor('gray')
          List({ space: 8 }) {
            //循环
            ForEach(
              this.items,
              (Item: Items) => {
                ListItem() {
                  //调用自定义构建函数(传参)----------自定义构建函数
                  ShopList(Item)
                }
              }
            )
          }
          .height('100%')
          .width('100%')
          .backgroundColor('#EFEFEF')
          .padding(10)
        }
      }
    }
    
    
  • @Styles装饰器(仅可以封装组件通用属性)

    class Items {
      ImageName: ResourceStr
      ShopName: string
      ShopPrice: number
      ShopPreferential: number
    
      constructor(ImageName: ResourceStr, ShopPreferential: number) {
        console.log('构造函数')
        this.ImageName = ImageName
        this.ShopName = ShopName
        this.ShopPrice = ShopPrice
        this.ShopPreferential = ShopPreferential
      }
    }
    
    //公共全局样式
    @Styles function publicStyle(){
      .height('100%')
      .width('100%')
      .backgroundColor('#EFEFEF')
      .padding(10)
    }
    
    @Entry
    @Component
    struct ItemPage {
      //商品数据
      private items: Array<Items> = [
        new Items($r('app.media.icon'), 0)
      ]
    
      build() {
    
        Column() {
    
          ShopTitle({ title: '商品列表' })
            .padding(10)
            .backgroundColor('gray')
            
          List({ space: 8 }) {
            ForEach(
              this.items,
              (Item: Items) => {
                ListItem() {
                  ShopList(Item)
                }
              }
            )
          }
          .publicStyle()//调用全局样式
        }
      }
    }
    
  • @Extend装饰器(仅可定义在全局,可以设置组件特有属性)

    @Extend(Text) function TextStyle(size:number,color:string='black') {
      .fontSize(size)
      .fontColor(color)
    }
    
    //构建函数
    @Builder function ShopList(Item: Items) {
      Row() {
        Image(Item.ImageName)
          .width(70)
          .height(70)
          .margin(20)
        Column() {
          if (Item.ShopPreferential) {
            Text(Item.ShopName)
              .TextStyle(20)
              .fontWeight(FontWeight.Bold)
            Text('原价:¥' + Item.ShopPrice)
              .TextStyle(18,'gray')//调用私有属性的全局方法
              .decoration({ type: TextDecorationType.LineThrough, color: 'gray' })
            Text('折扣价:¥' + (Item.ShopPrice - Item.ShopPreferential))
              .TextStyle(18,'red')//调用私有属性的全局方法
            Text('补贴:¥' + Item.ShopPreferential)
              .TextStyle(18,'red')//调用私有属性的全局方法
          } else {
            Text(Item.ShopName)
              .TextStyle(20)
              .fontWeight(FontWeight.Bold)
            Text('¥' + Item.ShopPrice)
              .TextStyle(18,'red')
          }
        }
        .height('100%')
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Start)
      }
      .height(100)
      .width('95%')
      .backgroundColor('#fff')
      .margin({
        top: 20,
      })
      .borderRadius(15)
    }
    

6. 状态管理

  • 状态(State):指驱动视图更新的数据(被装饰器标记的变量)

  • 视图(View):基于UI描述渲染得到用户界面

    说明 :

    1. @State装饰器标记的变量必须初始化,不能为空值
    2. @State支持Object、class、string、number、boolean、enum类型以及这些类型的数组
    3. 嵌套类型以及数组中的对象属性无法触发视图更新
  • @Prop和@Link(可以跨组件提供类似于@State和@Link的双向同步)

    • @prop和@link使用修饰符装饰变量不能给变量进行初始化
    • @link修饰的变量,父组件传递时需要使用$引用
  • @ObjectLink和@Observed装饰器用于在设计嵌套对象或数组元素为对象的场景中进行双向数据同步

在这里插入图片描述

7. 页面路由

路由是指在应用程序中实现不同页面之间的跳转和数据传递

  • 页面栈的最大容量上限为32个页面,使用router.clear()方法可以清空页面栈,释放内存

  • Router有两种页面跳转模式,分别是:

    • router.pushUrl():目标也不会替换当前页,而是压入页面栈,因此可以用router.back()返回当前页
    • router.replaceUrl():目标页替换当前页,当前页会被销毁并释放资源,无法返回当前页
  • Router有两种页面实力模式,分别是:

    • Standard:标准实力模式,每次跳转都会新建一个目标页并压入栈顶,默认就是这种模式
    • Single:单实例模式,如果目标页已经在栈中,则离栈顶最近的同Url页面会被移动到底栈顶并重新加载
  • 步骤

      1. 首先要导入HarmonyOS提供的Router模块:

        import router from '@ohos.router'
        
      2. 利用Router实现跳转,返回等操作

        router.pushUrl(
            {
            	url:'page/ImagePage',//跳转的路径
            	params:{id:1}//可选,跳转时所带的参数
        	},
            router.RouterMode.Single,//页面模式
            err=>{
            if(err){
            	console.log('路由跳转失败!')
            //100001:内部错误,可能是渲染失败
            //100002:路由地址错误
            //100003:路由栈中页面超过32
        	}
            }
        )
        
      3. 跳转到的页面获取参数

        //获取获取的参数
        params:any = router.getParams()
        //返回上一页
        router.back()
        //返回到指定的页面,并携带参数
        router.back({
            url:'page/Index'params:{id:19}
        })
        
      4. 注意 路由跳转时需要配置路径(src/main/resources/base/profile/)下的main_pages.json文件,需要把要跳转的路径都配置上,要不然跳转不了!!!

8. 属性动画和显式动画

在这里插入图片描述

9. 转场动画

组件的插入、删除过程即为组件本身的转场过程,组件的插入、删除动画称为组件内转场动画。通过组件内转场动画,可定义组件出现、消失的效果。
js transition(value: TransitionOptions)
注意:transition函数的入参为组件内转场的效果,可以定义平移、透明度、旋转、缩放这几种转场样式的单个或者组合的转场效果,必须和animateTo一起使用才能产生组件转场效果
1.常见用法:
type用于指定当前的transition动效生效在组件的变化场景,类型为TransitionType
js Button() .transition({ type: TransitionType.All,scale: { x: 0,y: 0 } })

  • TransitionType.All:组件的插入、删除使用同一个动画效果
  • TransitionType.Insert:组件插入的效果
  • TransitionType.Delete:组件删除的效果
    2.if/else产生组件内转场动画
 @Entry
 @Component
 struct IfElseTransition {
   @State flag: boolean = true;
   @State show: string = 'show';
   build() {
     Column() {
       Button(this.show).width(80).height(30).margin(30)
         .onClick(() => {
           if (this.flag) {
             this.show = 'hide';
           } else {
             this.show = 'show';
           }
           animateTo({ duration: 1000 }, () => {
             // 动画闭包内控制Image组件的出现和消失
             this.flag = !this.flag;
           })
         })
       if (this.flag) {
         // Image的出现和消失配置为不同的过渡效果
         Image($r('app.media.mountain')).width(200).height(200)
           .transition({ type: TransitionType.Insert, translate: { x: 200, y: -200 } })
           .transition({ type: TransitionType.Delete, opacity: 0, scale: { x: 0, y: 0 } })
       }
     }.height('100%').width('100%')
   }
 }

10. 网络连接-Http请求数据


 // 引入包名
 import http from '@ohos.net.http';
 
 // 每一个httpRequest对应一个HTTP请求任务,不可复用
 let httpRequest = http.createHttp();
 // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
 // 从API 8开始,使用on('headersReceive',Callback)替代on('headerReceive',AsyncCallback)。 8+
 httpRequest.on('headersReceive', (header) => {
     console.info('header: ' + JSON.stringify(header));
 });
 httpRequest.request(
     // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
     "EXAMPLE_URL",
     {
         method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
         // 开发者根据自身业务需要添加header字段
         header: {
             'Content-Type': 'application/json'
         },
         // 当使用POST请求时此字段用于传递内容
         extraData: {
             "data": "data to send",
         },
         expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
         usingCache: true, // 可选,默认为true
         priority: 1, // 可选,默认为1
         connectTimeout: 60000, // 可选,默认为60000ms
         readTimeout: 60000, // 可选,默认为60000ms
         usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
     }, (err, data) => {
         if (!err) {
             // data.result为HTTP响应内容,可根据业务需要进行解析
             console.info('Result:' + JSON.stringify(data.result));
             console.info('code:' + JSON.stringify(data.responseCode));
             // data.header为HTTP响应头,可根据业务需要进行解析
             console.info('header:' + JSON.stringify(data.header));
             console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
             // 取消订阅HTTP响应头事件
             httpRequest.off('headersReceive');
             // 当该请求使用完毕时,调用destroy方法主动销毁
             httpRequest.destroy();
         } else {
             console.info('error:' + JSON.stringify(err));
             // 取消订阅HTTP响应头事件
             httpRequest.off('headersReceive');
             // 当该请求使用完毕时,调用destroy方法主动销毁。
             httpRequest.destroy();
         }
     }
 );

原文地址:https://blog.csdn.net/weixin_45598400/article/details/135503759

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读1.4k次。被@Observed装饰的类,可以被观察到属性的变化;子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中是属性,这个属性同样也需要被@Observed装饰。单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。_鸿蒙ark对象数组
文章浏览阅读1k次。Harmony OS_harmonyos创建数据库
文章浏览阅读1.1k次,点赞25次,收藏23次。自定义组件Header.ets页面(子组件)//自定义组件@Component//组件声明private title:ResourceStr//接收的参数build(){Row() {index.ets(父组件)//导入自定义组件@Entry@Componentbuild() {Column() {/*** 1. 自定义组件调用-----自定义组件------* 2. 在调用的组件上设置样式*/ShopTitle({ title: '商品列表' })
文章浏览阅读952次,点赞11次,收藏25次。ArkUI是一套构建分布式应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时界面预览工具,帮助您提升移动应用界面开发效率30%。您只需使用一套ArkTS API,就能在Android、iOS、鸿蒙多个平台上提供生动而流畅的用户界面体验。_支持ios 安卓 鸿蒙next的跨平台方案
文章浏览阅读735次。​错误: 找不到符号符号: 变量 Layout_list_item位置: 类 ResourceTable_错误: 找不到符号 符号: 变量 resourcetable 位置: 类 mainabilityslice
文章浏览阅读941次,点赞23次,收藏21次。harmony ARKTS base64 加解密_鸿蒙 鸿蒙加解密算法库
文章浏览阅读860次,点赞21次,收藏24次。使用自定义布局,实现子组件自动换行功能。图1自定义布局的使用效果创建自定义布局的类,并继承ComponentContainer,添加构造方法。//如需支持xml创建自定义布局,必须添加该构造方法实现ComponentContainer.EstimateSizeListener接口,在onEstimateSize方法中进行测量。......@Override//通知子组件进行测量//关联子组件的索引与其布局数据idx++) {//测量自身。_鸿蒙javaui
文章浏览阅读917次,点赞25次,收藏25次。这里需要注意的是,真机需要使用华为侧提供的测试机,测试机中会安装纯鸿蒙的系统镜像,能够体验到完整的鸿蒙系统功能,纯鸿蒙应用目前还不能完美地在 HarmonyOS 4.0 的商用机侧跑起来。当前,真机调试需要使用华为侧提供的测试机,测试机中会安装纯鸿蒙的系统镜像,能够体验到完整的鸿蒙系统功能,纯鸿蒙应用目前还不能完美地在 HarmonyOS 4.0 的商用机侧跑起来。另外,由于样式的解析是基于组件文件的纬度的,因此样式文件只能应用于被其引用的组件文件中,而不能跨文件应用,并且样式文件也只支持类选择器。_鸿蒙 小程序
文章浏览阅读876次,点赞17次,收藏4次。2. HarmonyOS应用开发DevEcoStudio准备-1HUAWEI DevEco Studio为运行在HarmonyOS和OpenHarmony系统上的应用和服务(以下简称应用/服务)提供一站式的开发平台。
文章浏览阅读811次。此对象主要映射JSON数组数据,比如服务器传的数据是这样的。_arkts json
文章浏览阅读429次。鸿蒙小游戏-数字华容道_华为鸿蒙手机自带小游戏
文章浏览阅读1.1k次,点赞24次,收藏19次。Ability是应用/服务所具备的能力的抽象,一个Module可以包含一个或多个Ability。
文章浏览阅读846次。本文带大家使用MQTT协议连接华为IoT平台,使用的是E53_IA1 智慧农业扩展板与 BearPi-HM_Nano 开发主板_mqtt 如何对接第三方iot平台
文章浏览阅读567次。HarmonyOS_arkts卡片
文章浏览阅读1k次,点赞19次,收藏20次。ArkTS开发鸿蒙OS连接mongoDB(后端node.js)2024最新教程
文章浏览阅读1.2k次,点赞23次,收藏15次。HarmonyOS与OpenHarmony(1)本质上的不同是:HarmonyOS是鸿蒙操作系统,而OpenHarmony则是从开源项目。这里可以联想一下Android,比如小米手机在Android开源系统的基础上开发了MIUI的手机操作系统,HarmonyOS就类似于MIUI,OpenHarmony类似Android基础底座。(2)HarmonyOS:是双框架,内聚了AOSP(Android Open Source Project )和OpenHarmony等。_鸿蒙模拟器开了怎么跑代码
文章浏览阅读1.1k次,点赞21次,收藏21次。鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Navigation组件。
文章浏览阅读2k次。由于之前的哥们匆忙离职了,所以鸿蒙手表项目的新版本我临时接过来打包发布,基本上之前没有啥鸿蒙经验,但是一直是做Android开发的,在工作人员的指导下发现打包配置基本上和Android一样,所以这些都不是问题,这里记录一下使用过程中遇到的问题。!过程和遇到的问题基本上都讲解了,关机睡觉,打卡收工。_鸿蒙系统adb命令
文章浏览阅读7.3k次,点赞9次,收藏29次。39. 【多选题】_column和row容器中,设置子组件在主轴方向上的对齐格式
文章浏览阅读1.1k次,点赞13次,收藏24次。18.鸿蒙HarmonyOS App(JAVA)日期选择器-时间选择器点击button按钮显示月份与获取的时间。_harmonyos农历获取