HarmonyOS NEXT 实战系列02-布局基础

编辑

  • ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。

1. ArkUI-布局-线性布局

线性布局(LinearLayout)是开发中最常用的布局,通过线性容器 Row 和 Column 构建。Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列。根据不同的排列方向,开发者可选择使用Row或Column容器创建线性布局。

① 基本使用

scss 复制代码
Column({ space: 20 }) {
  Row().width('90%').height(50).backgroundColor('#006699')
  Row().width('90%').height(50).backgroundColor('#006699')
  Row().width('90%').height(50).backgroundColor('#006699')
}.width('100%')

编辑

scss 复制代码
Row({ space: 20 }) {
  Row().width('10%').height(150).backgroundColor('#006699')
  Row().width('10%').height(150).backgroundColor('#006699')
  Row().width('10%').height(150).backgroundColor('#006699')
}.width('90%')

编辑

② 子元素主轴排列方式

编辑

属性 描述
Start 首端对齐
Center 居中对齐
End 尾部对齐
Spacebetween 两端对齐子元素之间间距相等
SpaceAround 子元素两侧间距相等第一个元素到行首的距离和最后一个元素到行尾的距离 是相邻元素之间距离的一半
SpaceEvenly 相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样

③ 子元素在交叉轴上的对齐方式

Column 组件 HorizontalAlign

编辑

Row 组件 VerticalAlign

编辑

④ 自适应拉伸

scss 复制代码
    Row(){
      Text('关于微信')
      Blank()
      Text('版本 8.0.54')
      Text('  > ')
    }
    .width('100%')
    .height(50)

编辑

编辑

⑤ 自适应缩放

父容器尺寸确定时,使用layoutWeight属性设置子元素和兄弟元素在主轴上的权重,忽略元素本身尺寸设置,使它们在任意尺寸的设备下自适应占满剩余空间。

scss 复制代码
Row() {
      Column() {
        Text('layoutWeight(1)')
          .textAlign(TextAlign.Center)
      }
      .layoutWeight(1)
      .backgroundColor('#0099ff')
      .height('100%')

      Column() {
        Text('layoutWeight(2)')
          .textAlign(TextAlign.Center)
      }
      .layoutWeight(2)
      .backgroundColor('#00eeff')
      .height('100%')

      Column() {
        Text('layoutWeight(3)')
          .textAlign(TextAlign.Center)
      }
      .layoutWeight(3)
      .backgroundColor('#0099ff')
      .height('100%')

    }
    .height(100)

编辑

2. ArkUI-布局-基础组件

基础组件:Text Button Image TextInput ...

通用属性:width() height() size() backgroundColor() margin() padding() ...

尺寸单位:vp fp ...

  • vp

虚拟像素 (virtual pixel) 是一台设备针对应用而言所具有的虚拟尺寸 (区别于屏幕硬件本身的像素单位)。vp 是灵活的单位,它可在任何屏幕上缩放以具有统一的尺寸体量。它提供了一种灵活的方式来适应不同屏幕密度的显示效果。

编辑

使用虚拟像素,使 UI 元素在不同密度的设备上具有一致性大小视觉感受

  • fp

字体像素 (font pixel)默认情况下与 vp 相同,即默认情况下 1 fp = 1vp。如果用户在设置中选择了更大的字体,字体的实际显示大小就会在 vp 的基础上乘以 scale 系数,即 1 fp = 1 vp * scale。

3. ArkUI-布局-常见样式

① 文本 参考链接

scss 复制代码
// 颜色
Text('字体颜色')
        .fontColor(Color.Pink)
scss 复制代码
// 尺寸
Text('字体大小')
        .fontSize(30)
scss 复制代码
// 字重
Text('字体粗细')
        .fontWeight(FontWeight.Bold)
scss 复制代码
// 行高
Text('HarmonyOS 是新一代的智能终端操作系统,为不同设备的智能化、互联与协同提供了统一的语言。带来简洁,流畅,连续,安全可靠的全场景交互体验。')
        .lineHeight(40)
scss 复制代码
// 溢出隐藏
Text('HarmonyOS 是新一代的智能终端操作系统,为不同设备的智能化、互联与协同提供了统一的语言。带来简洁,流畅,连续,安全可靠的全场景交互体验。')
        .maxLines(2)
        // 超长文本使用省略号代替
        .textOverflow({overflow: TextOverflow.Ellipsis})

② 背景 参考链接

  • 颜色、图片
scss 复制代码
// 背景颜色
Text('组件')
        .width(300)
        .height(100)
        .backgroundColor(Color.Pink)
scss 复制代码
// 背景图片 
Text('组件')
        .width(300)
        .height(100)
        .backgroundImage($r('app.media.flower'))

编辑

③ 间距 参考链接

编辑

  • 内间距、外间距
less 复制代码
// 内间距
Text('文字')
        .backgroundColor(Color.Pink)
        // 单值:四个方向padding相同
        .padding(20)
        // 对象:单独设置某个方向
        .padding({
          top: 10,
          right: 20,
          bottom: 40,
          left: 80
        })
less 复制代码
// 外间距
Text('文字')
          .backgroundColor(Color.Orange)
        // 单值:四个方向margin相同
         .margin(20)
        // 对象:单独设置某个方向
          .margin({
            top: 10,
            right: 20,
            bottom: 40,
            left: 80
          })

④ 边框 参考链接

  • 边框、圆角
less 复制代码
Text('边框')
        .width(100)
        .height(40)
        // 红色 虚线 边框
        .border({width: 1, color: 'red', style: BorderStyle.Dashed})
       // 四个方向 
       .border({
          width: {left: 1, top: 3, right: 5, bottom: 7},
          color: {left: 'red', top: '#ff0', right: '#f60', bottom: '#ccc'},
          style: {top: BorderStyle.Dashed, right: BorderStyle.Dotted}
        })
scss 复制代码
Text('圆角')
        .width(100)
        .height(40)
        .backgroundColor('#f60')
        // 四个角一致
        .borderRadius(5)
        // 四个角不一致
       .borderRadius({
          topLeft: 5,
          topRight: 10,
          bottomRight: 20,
          bottomLeft: 40
        })

1.18 ArkUI-布局-@Extend

作用:扩展原生组件样式,用于样式的重用

语法:@Extend(UIComponentName) function functionName { ... }

代码:

typescript 复制代码
import { promptAction } from '@kit.ArkUI'

@Extend(Button)
function customButton(color: Color, message: string) {
  .fontColor(color)
  .backgroundColor('#CCCCCC')
  .fontSize(14)
  .height(50)
  .onClick(() => {
    promptAction.showToast({ message: message })
  })
}

@Entry
@Component
struct TestPage {
  build() {
    Column({ space: 20 }) {
      // Button('按钮1')
      //   .fontColor(Color.Red)
      //   .backgroundColor('#CCCCCC')
      //   .fontSize(14)
      //   .height(50)
      //   .onClick(() => {
      //     promptAction.showToast({ message: '红色' })
      //   })
      // Button('按钮2')
      //   .fontColor(Color.Green)
      //   .backgroundColor('#CCCCCC')
      //   .fontSize(14)
      //   .height(50)
      //   .onClick(() => {
      //     promptAction.showToast({ message: '绿色' })
      //   })
      Button('按钮1')
        .customButton(Color.Red, '红色')
      Button('按钮2')
        .customButton(Color.Green, '绿色')
    }
    .padding(50)
  }
}

注意:

  • @Eextend 仅在全局定义,不支持组件内部,不支持 export

4. ArkUI-布局-@Styles

作用:可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用,仅支持通用属性通用事件

语法:

  • 全局 @Styles function functionName() { ... }
  • 组件 @Styles functionName(){ ... }

代码:

scss 复制代码
@Entry
@Component
struct TestPage {
  @Styles
  customButton() {
    .width(200)
    .height(100)
    .borderRadius(20)
  }

  build() {
    Column({ space: 20 }) {
      // Text('灰色按钮')
      //   .width(200)
      //   .height(100)
      //   .borderRadius(20)
      //   .backgroundColor('#CCCCCC')
      //   .textAlign(TextAlign.Center)
      // Image($r('app.media.flower'))
      //   .width(200)
      //   .height(100)
      //   .borderRadius(20)
      Text('灰色按钮')
        .customButton()
        .backgroundColor('#CCCCCC')
        .textAlign(TextAlign.Center)
      Image($r('app.media.flower'))
        .customButton()
    }
    .padding(50)
  }
}

注意:@Styles 方法不能有参数

5. ArkUI-布局-@Builder

作用:轻量的UI元素复用机制@Builder,包含样式和事件

语法:

  • 全局 @Builder function MyGlobalBuilderFunction() { ... }
    • 使用 MyGlobalBuilderFunction()
  • 私有 @Builder MyBuilderFunction() {}
    • 使用 this.MyBuilderFunction()

代码:

typescript 复制代码
import { promptAction } from '@kit.ArkUI'

@Entry
@Component
struct TestPage {
  @Builder
  navItem(icon: Resource, text: string) {
    Column() {
      Image(icon)
        .width(24)
        .aspectRatio(1)
      Text(text)
        .fontSize(12)
    }
    .layoutWeight(1)
    .onClick(() => {
      promptAction.showToast({ message: text })
    })
  }

  build() {
    Column({ space: 20 }) {
      Row()
        .layoutWeight(1)
      Row() {
        // Column(){
        //   Image($r('sys.media.ohos_ic_public_email'))
        //     .width(24)
        //     .aspectRatio(1)
        //   Text('邮件')
        //     .fontSize(12)
        // }
        // .layoutWeight(1)
        // .onClick(() => {
        //   promptAction.showToast({ message: '邮件' })
        // })
        // Column(){
        //   Image($r('sys.media.ohos_ic_public_express'))
        //     .width(24)
        //     .aspectRatio(1)
        //   Text('快递')
        //     .fontSize(12)
        // }
        // .layoutWeight(1)
        // .onClick(() => {
        //   promptAction.showToast({ message: '快递' })
        // })
        this.navItem($r('sys.media.ohos_ic_public_email'), '邮件')
        this.navItem($r('sys.media.ohos_ic_public_express'), '快递')
      }
      .height(50)
      .width('100%')
      .backgroundColor('#cccccc')
    }
    .width('100%')
    .height('100%')
  }
}

注意:@Builder 是轻量UI封装,将来的自定义组件封装能力更强

6. 条件&循环渲染

① 条件渲染

scss 复制代码
  // 铜牌 | 银牌 | 金牌
  // level: number = 0 | 1 | 2

  @Builder
  LevelBuilder(level: number) {
    if (level === 1) {
      Text('🥈')
    } else if (level === 2) {
      Text('🏅')
    } else {
      Text('🥉')
    }
  }
scss 复制代码
Column({ space: 20 }) {
        Row(){
          Text('小红')
          this.LevelBuilder(1)
        }
        Row(){
          Text('小娇')
          this.LevelBuilder(2)
        }
      }
      .layoutWeight(1)
  • 条件渲染可根据应用的不同状态,使用if、else和else if渲染对应状态下的UI内容。

② 循环渲染 参考链接

ForEach(数组,组件生成函数(item,i),建值生成函数(item,i))

scss 复制代码
interface PlayerItem {
  name: string
  level: number
}

@Entry
@Component
struct TestPage {
  // 铜牌 | 银牌 | 金牌
  // level: number = 0 | 1 | 2

  @Builder
  LevelBuilder(level: number) {
    if (level === 1) {
      Text('🥈')
    } else if (level === 2) {
      Text('🏅')
    } else {
      Text('🥉')
    }
  }

  playerList: PlayerItem[] = [
    { name: '小华', level: 2 },
    { name: '小红', level: 1 },
    { name: '小芳', level: 1 },
    { name: '小朱', level: 0 },
  ]

  build() {
    Column({ space: 20 }) {
      ForEach(this.playerList, (item: PlayerItem) => {
        Row() {
          Text(item.name)
          this.LevelBuilder(item.level)
        }
      })
    }
    .width('100%')
    .height('100%')
  }
}
  • ForEach接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。

相关推荐
二流小码农13 分钟前
鸿蒙开发:自定义一个搜索模版
android·ios·harmonyos
别说我什么都不会43 分钟前
鸿蒙(HarmonyOS)性能优化实战-HiDumper命令行工具优化性能
性能优化·harmonyos
陈无左耳、1 小时前
HarmonyOS学习第20天:让应用“找准方向”的地图与定位秘籍
学习·华为·harmonyos
zhousg5 小时前
HarmonyOS NEXT 实战系列01-ArkTS基础
harmonyos
别说我什么都不会5 小时前
鸿蒙(HarmonyOS)性能优化实战-性能测试工具SmartPerf Editor
性能优化·harmonyos
趋势大仙7 小时前
harmony Next 基础知识点1
开发语言·华为·harmonyos
__Benco7 小时前
OpenHarmony子系统开发 - 模块配置规则
人工智能·harmonyos
轻口味7 小时前
【每日学点HarmonyOS Next知识】类型判断、刘海高度、隐私弹窗、滑动下一页效果、清楚缓存
缓存·华为·harmonyos·harmonyosnext
png8 小时前
从零开始纯血鸿蒙天气预报-主界面(2)
harmonyos·arkui