自学内容网 自学内容网

HarmonyOS开发(ArkUI简单使用)

一、开发准备

1.官网 

https://developer.huawei.com/consumer/cn/

2.工具

DevEco Studio

下载: 下载中心 | 华为开发者联盟-HarmonyOS开发者官网,共建鸿蒙生态

3.安装

4.开发组件ArkTs

ArkTS是HarmonyOS主力应用开发语言。它在TypeScript(简称TS)的基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等相应的能力,让开发者以更简洁、更自然的方式开发跨端应用。

5.快速上手

 

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

7.安装模拟器

 

 

解决措施

首先打开控制面板 > 程序 > 程序与功能 > 启动或关闭Windows功能,找到并勾选“Hyper-V”、“Windows虚拟机监控程序平台”、“虚拟机平台”,点击确定并重启电脑。若勾选后启动模拟器仍然提示该错误,需要以管理员权限打开命令行窗口并执行:`bcdedit /set hypervisorlaunchtype auto`并重启电脑。

二、ArkUI

ArkUI(方舟UI框架)为应用的UI开发提供了完整的基础设施,包括简洁的UI语法、丰富的UI功能(组件、布局、动画以及交互事件),以及实时界面预览工具等,可以支持开发者进行可视化界面开发。

1.图片显示组件
a.声明Image组件并设置图片源 
Image(src:string|PixelMap|Resource)

Image('https://xxx.png')
Image(PixelMapObject)
Image($r('app.media.mate60'))
Image($rawfile('mate60.png'))

string格式,通常用来加载网络图片,需要申请网络访问权限:obos.permission.INTERNET

PixelMap格式,可以加载像素图,常用在图片编辑器中

Resource格式,加载本地图片,推荐使用

b.添加图片属性
Image($r('app.media.icon'))
    .width(100)
    .height(120)
    .borderRadius(10)
    .interpolation(ImageInterpolation.High)
2.文本显示组件
a.声明Text组件并设置文本内容
Text(content?:string|Resource)

Text('图片宽度')
Text($r('app.string.width_label'))

string格式,直接写文本内容

Resource格式,读取本地资源文件

 b.添加图片属性
Text('注册账号')
    .lineHeight(32)
    .fontSize(20)
    .fontColor('#ff1876f8')
    .fontWeight(FontWeight.Medium)
 3.文本输入框
a.声明TextInput组件
TextInput({placeHolder?:ResourceStr,text?:ResourceStr})

TextInput({placeHolder:'请输入账号或手机号'})

placeHolder输入框无输入时的提示文本

text输入框当前的文本内容

 b.添加属性和事件
TextInput({text:'请输入账号或手机号'})
    .width(150)
    .height(30)
    .backgroundColor('#fff')
    .type(InputType.Password)
    .onChange(value=>{console.log(value)})
 4.按钮输入框
a.声明Button组件,label是按钮文字
Button(label?:ResourceStr)

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

文字型按钮

自定义按钮,在Button组件内嵌套其他组件

 b.添加属性和事件
Button('点我')
    .width(100)
    .height(30)
    .type(ButtonType.Normal)
    .onClick(()=>{})
 5.滑动条组件
Slider(options?:SilderOptions)

Slider({
     min:10,
     max:100,
     value:30,
     step:10,
     style:SliderStyle.OutSet,
     direction:Axis.Horizontal,
     reverse:false
})
     .width('90%')
     .showTips(true)
     .blockColor('#36d')
     .onChange(()=>{})
6.布局组件

Column容器从上往下排列

Row容器从左往右排列

间距:Space

7.示例

@Entry
@Component
struct Index {
  @State imageWidth: number = 250;
  build() {
      Column() {
        Row(){
          Image('https://tse4-mm.cn.bing.net/th?id=OIP.nweYnRD-9eFP3nNgNDU9gwHaGt&pid=1.7&w=217&h=198&c=8&dpr=0.9')
            .width(this.imageWidth)
        }
        .width('100%')
        .height(400)
        .justifyContent(FlexAlign.Center)
        Row(){
          Text($r('app.string.width_label'))
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
          TextInput({ placeholder: '请输入图片宽度', text: this.imageWidth.toFixed(0) })
            .width(150)
            .backgroundColor('#fff')
            .type(InputType.Number)
            .onChange(val=>{
              console.log(val)
              this.imageWidth=parseInt(val)
            })
        }
        .width('100%')
        .height(60)
        .justifyContent(FlexAlign.SpaceAround)
        Divider().width('91%')
        Row(){
          Button('缩小')
            .width(80)
            .height(30)
            .type(ButtonType.Normal)
            .onClick(()=>{
              if(this.imageWidth>=10){
                this.imageWidth-=10
              }
            })
          Button('放大')
            .width(80)
            .height(30)
            .type(ButtonType.Normal)
            .onClick(()=>{
              if(this.imageWidth<=340){
                this.imageWidth+=10
              }
            })
        }
        .width('100%')
        .height(60)
        .justifyContent(FlexAlign.SpaceAround)
        Slider({
          min:10,
          max:340,
          value:this.imageWidth,
          step:10,
          style:SliderStyle.OutSet,
          direction:Axis.Horizontal,
          reverse:false
        })
          .width('90%')
          .showTips(true)
          .trackThickness(8)
          .blockColor('#36d')
          .onChange((val)=>{this.imageWidth=val})
      }
      .width('100%')
      .height('100%')
  }
}

 三、渲染控制(ForEach,if-else)

1.ForEach
a.语法
ForEach(
    //要遍历的数组数据
    arr:Array,

    //页面组件生成函数
    (item:any,index?:number)=>{
        Row(){
            Image('mate60.jpg')
            Column(){
                Text('mate60')
                Text('12700.00')
            }
        }
    },

    //键生成函数,为数组每一项生成一个唯一标识,组件是否重新渲染的判断标准
    keyGenerator?:(item:any,index?:numbe):string=>{
    
    }
)
b.示例

class Item {
  name:string
  image:ResourceStr
  price:number
  constructor( name:string, image:ResourceStr, price:number) {
    this.name=name
    this.image=image
    this.price=price
  }
}
@Entry
@Component
struct Index {
  private items:Array<Item>=[
    new Item('华为Mate60',$r('app.media.mate'),6999),
    new Item('华为MateBookProX',$r('app.media.mate'),13999),
    new Item('华为WatchGT4',$r('app.media.mate'),1438),
    new Item('华为FreeBudPro3',$r('app.media.mate'),1499),
    new Item('华为MateX5',$r('app.media.mate'),12999)
  ]
  build() {
      Column({space:8}) {
        Row(){
          Text('商品列表')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
        }
        .width('100%')
        .height(60)
        .margin({bottom:20})

        ForEach(
          this.items,
          (item:Item)=>{
            Row({space:10}){
              Image(item.image)
                .width('20%')
              Column({space:4}){
                Text(item.name)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                Text(`¥ ${item.price}`)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                  .fontColor('red')
              }
              .alignItems(HorizontalAlign.Start)
            }
            .width('92%')
            .height(100)
            .padding(10)
            .backgroundColor('#fff')
            .borderRadius(20)
            .justifyContent(FlexAlign.Start)
          }
        )
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#ccc')
  }
}
 2.if-else条件渲染

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 Index {
  private items:Array<Item>=[
    new Item('华为Mate60',$r('app.media.mate'),6999,500),
    new Item('华为MateBookProX',$r('app.media.mate'),13999),
    new Item('华为WatchGT4',$r('app.media.mate'),1438),
    new Item('华为FreeBudPro3',$r('app.media.mate'),1499),
    new Item('华为MateX5',$r('app.media.mate'),12999)
  ]
  build() {
      Column({space:8}) {
        Row(){
          Text('商品列表')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
        }
        .width('100%')
        .height(60)
        .margin({bottom:20})

        ForEach(
          this.items,
          (item:Item)=>{
            Row({space:10}){
              Image(item.image)
                .width('20%')
              Column({space:4}){
                if(item.discount){
                  Text(item.name)
                    .fontSize(20)
                    .fontWeight(FontWeight.Bold)
                  Text(`原件¥ ${item.price}`)
                    .fontSize(16)
                    .fontWeight(FontWeight.Bold)
                    .fontColor('#ccc')
                    .decoration({type:TextDecorationType.LineThrough})
                  Text('折扣价¥ '+(item.price-item.discount))
                    .fontSize(20)
                    .fontWeight(FontWeight.Bold)
                    .fontColor('red')
                  Text(`补贴¥ ${item.discount}`)
                    .fontSize(20)
                    .fontWeight(FontWeight.Bold)
                    .fontColor('red')
                }else{
                  Text(item.name)
                    .fontSize(20)
                    .fontWeight(FontWeight.Bold)
                  Text(`¥ ${item.price}`)
                    .fontSize(20)
                    .fontWeight(FontWeight.Bold)
                    .fontColor('red')
                }
              }
              .alignItems(HorizontalAlign.Start)
            }
            .width('92%')
            .height(120)
            .padding(10)
            .backgroundColor('#fff')
            .borderRadius(20)
            .justifyContent(FlexAlign.Start)
          }
        )
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#ccc')
  }
}
3.List

列表List是一种复杂容器,具备以下特点:

列表项ListItem数量过多超出屏幕后,会自动提供滚动功能

列表项ListItem既可以纵向排列,也可以横向排列

a.语法
List({space:10}){
    ForEach([1,2,3,4],(item)=>{
        ListItem(){
         //列表项内容,只能包含一个根组件
        }
    })
}
.width('100%')
.listDirection(Axis.Vertical)//列表方向,默认纵向垂直,水平方向Horizontal
b.示例

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 Index {
  private items:Array<Item>=[
    new Item('华为Mate60',$r('app.media.mate'),6999,500),
    new Item('华为MateBookProX',$r('app.media.mate'),13999),
    new Item('华为WatchGT4',$r('app.media.mate'),1438),
    new Item('华为FreeBudPro3',$r('app.media.mate'),1499),
    new Item('华为MateX5',$r('app.media.mate'),12999),
    new Item('华为WatchGT4',$r('app.media.mate'),1438),
    new Item('华为FreeBudPro3',$r('app.media.mate'),1499),
    new Item('华为MateX5',$r('app.media.mate'),12999)
  ]
  build() {
      Column({space:8}) {
        Row(){
          Text('商品列表')
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
        }
        .width('100%')
        .height(30)
        .margin({bottom:20})

        List({space:8}){
          ForEach(this.items,(item:Item)=>{
            ListItem(){
              //列表项内容,只能包含一个根组件
              Row({space:10}){
                Image(item.image)
                  .width('20%')
                Column({space:4}){
                  if(item.discount){
                    Text(item.name)
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                    Text(`原件¥ ${item.price}`)
                      .fontSize(16)
                      .fontWeight(FontWeight.Bold)
                      .fontColor('#ccc')
                      .decoration({type:TextDecorationType.LineThrough})
                    Text('折扣价¥ '+(item.price-item.discount))
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                      .fontColor('red')
                    Text(`补贴¥ ${item.discount}`)
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                      .fontColor('red')
                  }else{
                    Text(item.name)
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                    Text(`¥ ${item.price}`)
                      .fontSize(20)
                      .fontWeight(FontWeight.Bold)
                      .fontColor('red')
                  }
                }
                .alignItems(HorizontalAlign.Start)
              }
              .width('92%')
              .height(120)
              .padding(10)
              .backgroundColor('#fff')
              .borderRadius(20)
              .justifyContent(FlexAlign.Start)
            }
          })
        }
        .width('100%')
        .layoutWeight(1)
      }
  }
}

四、自定义组件

1.拆分组件
@Component
struct Com {
  private title:string=''
  build(){
    //组件UI描述 
  }
}

@Component
struct XxxPage {
  build(){
    //使用组件
    Com({title:'标题'})
  }
}
2.在页面中引入Header组件
3.全局自定义构建函数
@Builder function XxxBuilder(){
    //UI描述
}
@Component
struct XxxPage {
    build(){
        XxxBuilder()
    }
}
4.局部自定义构建函数
@Component
struct XxxPage {
    @Builder YyyBuilder(){
        //UI描述
    }
    build(){
        this.YyyBuilder()
    }
}
5.全局公共样式函数

仅可封装组件的通用属性

@Styles function fillScreen(){
  .width('100%')
  .height('100%')
  .backgroundColor('#f6f6f6')
}
//Extend装饰器,继承模式,只能写在全局位置
@Extend(Text) function priceText(){
  .fontSize(20)
  .fontWeight(FontWeight.Bold)
  .fontColor('red')
}
6.局部公共样式函数
@Component
struct XxxPage {
    @Builder YyyBuilder(){
        //UI描述
    }
    build(){
        this.YyyBuilder()
        .fillScreen()
    }
    //局部公共样式函数
    @Styles  fillScreen(){
        .width('100%')
        .height('100%')
        .backgroundColor('#f6f6f6')
    }
}
7.示例

@Component
export struct Header {
  private title:ResourceStr|string=''
  build(){
    Row(){
      Image($r('app.media.left'))
        .width(30)
        .onClick(()=>{})
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
      Blank()
      Image($r('app.media.reset'))
        .width(24)
        .onClick(()=>{})
    }
    .width('100%')
    .height(30)
    .backgroundColor('#f6f6f6')
  }
}
import {Header} from '../Com/CommomCom';
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
  }
}
//全局自定义构建函数
// @Builder function ItemCard(item:Item){
// }
//全局公共样式函数
@Styles function fillScreen(){
  .width('100%')
  .height('100%')
  .backgroundColor('#f6f6f6')
}
//继承模式,只能写在全局位置
@Extend(Text) function priceText(){
  .fontSize(20)
  .fontWeight(FontWeight.Bold)
  .fontColor('red')
}

@Entry
@Component
struct Index {
  private items:Array<Item>=[
    new Item('华为Mate60',$r('app.media.mate'),6999,500),
    new Item('华为MateBookProX',$r('app.media.mate'),13999),
    new Item('华为WatchGT4',$r('app.media.mate'),1438),
    new Item('华为FreeBudPro3',$r('app.media.mate'),1499),
    new Item('华为MateX5',$r('app.media.mate'),12999),
    new Item('华为WatchGT4',$r('app.media.mate'),1438),
    new Item('华为FreeBudPro3',$r('app.media.mate'),1499),
    new Item('华为MateX5',$r('app.media.mate'),12999)
  ]
  build() {
      Column({space:8}) {
        //标题部分
        Header({title:'商品列表'})
          .margin({top:10})
          .padding({left:20,right:20})
        //商品列表部分
        List({space:8}){
          ForEach(this.items,(item:Item)=>{
            ListItem(){
              //列表项内容,只能包含一个根组件
              this.ItemCard(item)
            }
          })
        }
        .width('100%')
        .padding(20)
        .layoutWeight(1)
      }
    .fillScreen()
  }
  //局部自定义构建函数
  @Builder  ItemCard(item:Item){
  Row({space:10}){
    Image(item.image)
      .width('20%')
    Column({space:4}){
      if(item.discount){
        Text(item.name)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
        Text(`原件¥ ${item.price}`)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor('#ccc')
          .decoration({type:TextDecorationType.LineThrough})
        Text('折扣价¥ '+(item.price-item.discount))
          .priceText()
        Text(`补贴¥ ${item.discount}`)
          .priceText()
      }else{
        Text(item.name)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
        Text(`¥ ${item.price}`)
          .priceText()
      }
    }
    .alignItems(HorizontalAlign.Start)
  }
  .justifyContent(FlexAlign.Start)
  .CardItemScreen()
  }
  //局部公共样式函数
  @Styles  fillScreen(){
    .width('100%')
    .height('100%')
    .backgroundColor('#f6f6f6')
  }
  @Styles  CardItemScreen(){
    .width('100%')
    .height(120)
    .backgroundColor('#fff')
    .borderRadius(20)
  }
}


原文地址:https://blog.csdn.net/2301_79568779/article/details/142970969

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!