Skip to content
On this page

鸿蒙OS

1、简介

鸿蒙OS是一款基于Linux内核的物联网操作系统,支持物联网应用开发,支持多种硬件平台,支持多种应用场景,支持多种应用开发语言,支持多种应用运行环境。

2、开发环境

2.1、编辑器

https://developer.harmonyos.com/cn/develop/deveco-studio

2.2、编辑器操作

2.2.1、快捷键

格式化代码

shell
Option+Command+L

2.2.2、生成代码块

TIP

设置 -> Preferences -> Editor -> Live Templates -> 新建Template Group -> 新建Live Template

2.2.3、格式化代码

shell
Option+Command+F

### 2.2、开发文档
https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/start-overview-0000001478061421-V3

## 3、基础组件
### 3.1、Text
```js
// 普通Text
Text('普通Text')
  .fontSize(30)
  .fontColor(0xff0000)
  .fontWeight(FontWeight.Bold)
// 边框宽度+边框颜色
Text('边框宽度+边框颜色')
  .fontSize(30)
  .fontColor(0xff0000)
  .fontWeight(FontWeight.Bold)
  .border({ width: 2 })
  .borderColor(0xccc)
// 行高
Text('行高')
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .backgroundColor(Color.Gray)
  .lineHeight(100)
// 点击事件
Text(this.message)
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .onClick((e: ClickEvent) => {
    this.message = 'hello arkts'
    console.log('', e.x)
  })
// 装饰器
Text(this.message)
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .decoration({
    type: TextDecorationType.LineThrough, // None, Underline, Overline, LineThrough
    color: Color.Green
  })
// 对其方式
Text(this.message)
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .width('100%')
  .textAlign(TextAlign.End) // Start、Center、End
// 文本截断与maxLines配合
Text('文本截断文本截断文本截断文本截断')
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .width('100%')
  .maxLines(1)
  .textOverflow({
    overflow: TextOverflow.Ellipsis // Clip、Ellipsis、None
  })
// 文本间距
Text('文本间距')
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .letterSpacing(30)
// 文本大小写
Text('hello world')
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(0xff0000)
  .textCase(TextCase.UpperCase) //Normal、LowerCase、UpperCase

3、基础组件

3.2、Image

网络图需要申请网络权限

module.json5

js
{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "phone",
      "tablet"
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],
    ...
  }
}
js
// 网络图
Image('https://images.unsplash.com/photo-1682686581580-d99b0230064e?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D')
  .height(200)

// 本地media图
Image($r('app.media.icon'))
  .height(100)
  .interpolation(ImageInterpolation.High) // 图片插值,处理清晰度

// 本地rawfile图
Image($rawfile('icon.png'))
  .height(100)
  .interpolation(ImageInterpolation.High) // 图片插值,处理清晰度

// 图片缩放类型
Image($rawfile('icon.png'))
  .height(300)
  .objectFit(ImageFit.ScaleDown) // 比例展示
  .interpolation(ImageInterpolation.High) // 图片插值,处理清晰度

3.3、Button

js
// 普通按钮
Button('普通文本')

// 按钮类型
Button('普通文本', { type: ButtonType.Normal, stateEffect: true }) // Normal,Capsule,Circle

// 自定义内容
Button({ type: ButtonType.Normal, stateEffect: true }) {
  Row() {
    LoadingProgress().width(20).height(20).margin({ left: 12 }).color(0xFFFFFF)
    Text('loading').fontSize(12).fontColor(0xffffff).margin({ left: 5, right: 12 })
  }.alignItems(VerticalAlign.Center)
}.borderRadius(8).backgroundColor(0x317aff).width(90).height(40)

// 点击事件
Button('点击事件', { type: ButtonType.Normal, stateEffect: true })
  .onClick(() => {
    console.log('点击事件')
  })

// 按钮尺寸
Button('点击事件', { type: ButtonType.Normal, stateEffect: true })
  .width(100)
  .height(40)
  .margin({ top: 20 })

// 按钮状态配置
Button('点击状态配置')
  .stateStyles({
    pressed: {
      .backgroundColor(Color.Green)
    },
    normal: {
      .backgroundColor(Color.Yellow)
    }
  })
  .onClick((e) => {
    this.focusable1 = !this.focusable
    console.log('-------2');
  })

3.4、CheckBox

js
// 普通用法
Checkbox().select(true)

// 事件
Checkbox()
  .select(true)
  .onChange((value: boolean) => {
    console.info('Checkbox1 change is'+ value)
  })

// 自定义颜色
Checkbox()
  .select(true)
  .onChange((value: boolean) => {
    console.info('Checkbox1 change is'+ value)
  })

// 多选-分组
Checkbox({name: 'checkbox1',  group: 'checkboxGroup'})
  .select(true)
  .selectedColor(0xed6f21)
  .onChange((value: boolean) => {
    console.info('Checkbox1 change is'+ value)
  })
Checkbox({name: 'checkbox2',  group: 'checkboxGroup'})
  .select(false)
  .selectedColor(0x39a2db)
  .onChange((value: boolean) => {
    console.info('Checkbox2 change is'+ value)
  })
CheckboxGroup({ group: 'checkboxGroup' })
  .selectedColor('#007DFF')
  .onChange((itemName: CheckboxGroupResult) => {
    console.info("checkbox group content" + JSON.stringify(itemName))
  })

3.5、Radio

js
Radio({ value: 'Radio1', group: 'radioGroup' }).checked(true)
  .height(50)
  .width(50)
  .onChange((isChecked: boolean) => {
    console.log('Radio1 status is ' + isChecked)
  })
Radio({ value: 'Radio2', group: 'radioGroup' }).checked(false)
  .height(50)
  .width(50)
  .onChange((isChecked: boolean) => {
    console.log('Radio2 status is ' + isChecked)
  })

3.6、Progress

js
Progress({ value: 20, total: 150, type: ProgressType.Linear })
  .color(Color.Grey)
  .value(50)
  .width(100)
  .style({ strokeWidth: 20, scaleCount: 30, scaleWidth: 20 })

3.7、Slider

js
Slider({
  value: this.inSetValueTwo,
  min: 0,
  max: 100,
  step: 10,
  style: SliderStyle.InSet,
  direction: Axis.Horizontal,
})
  .showTips(true)
  .onChange((value: number, mode: SliderChangeMode) => {
    this.inSetValueTwo = value
    console.info('value:' + value + 'mode:' + mode.toString())
  })

3.8、Navigation && Navigator

js
@Entry
@Component
struct NavigationPage {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @State currentIndex: number = 0
  @State Build: Array<Object> = [
    {
      text: 'add',
      num: 0
    },
    {
      text: 'app',
      num: 1
    },
    {
      text: 'collect',
      num: 2
    }
  ]

  build() {
    Column() {
      Navigation() {
        TextInput({ placeholder: 'search...' })
          .width('90%')
          .height(40)
          .backgroundColor('#FFFFFF')
          .margin({ top: 8 })
        List({ space: 12, initialIndex: 0 }) {
          ForEach(this.arr, (item) => {
            ListItem() {
              Navigator({ target: 'pages/Index', type: NavigationType.Push }) {
                Text('' + item)
                  .width('90%')
                  .height(72)
                  .backgroundColor('#FFFFFF')
                  .borderRadius(24)
                  .fontSize(16)
                  .fontWeight(500)
                  .textAlign(TextAlign.Center)
              }.params({ text: item }) // 传参数到Detail页面
            }.editable(true)
          }, item => item)
        }
        .layoutWeight(1)
        .width('100%')
        .margin({ top: 12, left: '10%' })
      }
      .title(this.NavigationTitle)
      .titleMode(NavigationTitleMode.Full)
      .menus(this.NavigationMenus)
      .toolBar(this.NavigationToolbar)
      .hideTitleBar(false)
      .hideToolBar(false)
      .onTitleModeChange((titleModel: NavigationTitleMode) => {
        console.info('titleMode' + titleModel)
      })
    }.width('100%').height('100%').backgroundColor('#F1F3F5')
  }

  @Builder NavigationTitle() {
    Column() {
      Text('Title')
        .fontColor('#182431')
        .fontSize(30)
        .lineHeight(41)
        .fontWeight(700)
      Text('subtitle')
        .fontColor('#182431')
        .fontSize(14)
        .lineHeight(19)
        .opacity(0.4)
        .margin({ top: 2, bottom: 20 })
    }.alignItems(HorizontalAlign.Start)
  }

  @Builder NavigationMenus() {
    Row() {
      Image($r('app.media.icon'))
        .width(24)
        .height(24)
      Image($r('app.media.icon'))
        .width(24)
        .height(24)
        .margin({ left: 24 })
      Image($r('app.media.icon'))
        .width(24)
        .height(24)
        .margin({ left: 24 })
    }
  }

  @Builder NavigationToolbar() {
    Row() {
      ForEach(this.Build, item => {
        Column() {
          Image(this.currentIndex == item.num ? $r('app.media.icon') : $r('app.media.icon'))
            .width(24)
            .height(24)
          Text(item.text)
            .fontColor(this.currentIndex == item.num ? '#007DFF' : '#182431')
            .fontSize(10)
            .lineHeight(14)
            .fontWeight(500)
            .margin({ top: 3 })
        }.width(104).height(56).justifyContent(FlexAlign.Center)
        .onClick(() => {
          this.currentIndex = item.num
        })
      })
    }.backgroundColor(Color.White).width('100%').justifyContent(FlexAlign.SpaceEvenly)
  }
}

3.9、Dialog

4、组件进阶用法

4.1、@Builder自定义函数

js
// 全局自定义函数
@Builder function NavigationMenus() {
  Row() {
    Image($r('app.media.icon'))
      .width(24)
      .height(24)
  }
}

@Builder NavigationMenus() {
  Row() {
    Image($r('app.media.icon'))
      .width(24)
      .height(24)
  }
}

// 使用
build() {
  Column() {
    this.NavigationMenus()
  }
}

4.2、@BuilderParams自定义回调

js
@Component
struct Hello {
  @BuilderParam callback: () => void

  build() {
    Text('hello')
      .onClick(() => {
        this.callback && this.callback()
      })
  }
}

// 使用
hello() {
  console.log('callback=======')
}

hello1: () => void = () => {
  console.log('callback1=======')
}

Hello({ callback: () => {
  console.log("----")
}})
Hello({ callback: this.hello.bind(this) })
Hello({ callback: this.hello1 })
js
@Component
struct First {
  @BuilderParam child?: CustomBuilder

  build() {
    if (this.child) {
      this.child()
    }
  }
}

First({ child: this.NavigationTitle })

4.3、@Styles自定义样式

js
// 全局样式
@Styles function textStyle() {
  .backgroundColor(Color.Red)
}

// 组件样式
@Styles textStyle2() {
  .backgroundColor(Color.Red)
}

Text('------1111').textStyle()
Text('------2222').textStyle2()

4.4、@Extend扩展样式

js
// 全局组件扩展样式
@Extend(Text) function textExtend() {
  .fontColor(Color.Blue)
  .backgroundColor(Color.Green)
}

// 局部组件扩展样式
@Extend(Text) function textExtend() {
  .fontColor(Color.Blue)
  .backgroundColor(Color.Green)
}

4.5、自定义dialog

4.5.1、自定义dialog内容

js
@Entry
@Component
struct CallBackPage {
  @State message: string = 'Hello World'
  @State inputValue: string = 'click me'

  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialog1({
      inputValue: $inputValue
    }),
    // customStyle: true, // 自定义样式
  })
  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.dialogController.open()
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

@CustomDialog
struct CustomDialog1 {
  @Link inputValue: string
  controller: CustomDialogController

  build() {
    Column() {
      Text('change text').fontSize(20).margin({top: 20, bottom: 10})
      TextInput({ placeholder: '111', text: this.inputValue }).height(60).width('90%').onChange((v) => {
        this.inputValue = v
      })
    }
    .backgroundColor(Color.White)
    .borderRadius(8)
  }
}

4.5.2、自定义dialog样式

js
dialogController: CustomDialogController = new CustomDialogController({
  builder: CustomDialog1({
    inputValue: $inputValue
  }),
  customStyle: true, // 自定义样式
})

4.5.3、自定义回调

js
@Entry
@Component
struct CallBackPage {
  @State message: string = 'Hello World'
  @State inputValue: string = 'click me'

  dialogController: CustomDialogController = new CustomDialogController({
    builder: CustomDialog1({
      inputValue: this.inputValue,
      changeInputValue: (val: string) => {
        this.inputValue = val
      }
    }),
    customStyle: true, // 自定义样式
  })
  build() {
    Row() {
      Column() {
        Text(this.inputValue)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            this.dialogController.open()
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

@CustomDialog
struct CustomDialog1 {
  // @Link inputValue: string
  inputValue: string
  changeInputValue: (val: string) => void
  controller: CustomDialogController

  build() {
    Column() {
      Text('change text').fontSize(20).margin({top: 20, bottom: 10})
      TextInput({ placeholder: '111', text: this.inputValue }).height(60).width('90%').onChange((v) => {
        this.inputValue = v
      })
        .onChange((v) => {
          this.changeInputValue && this.changeInputValue(v)
        })
    }
    .backgroundColor(Color.White)
    .borderRadius(8)
  }
}

Last updated:

Released under the MIT License.