【鸿蒙开发实战】HarmonyOS之一多开发&项目搭建之自适应布局

前言

一、一多开发是什么意思?

一多开发是鸿蒙系统未来的趋势,

①页面适配问题 不同设备,屏幕尺寸、色彩风格,都存在差异
②功能兼容问题 不同设备,系统能力差异 eg.手机摄像头,手表测心率…
③工程如何组织 一个应用,实现一套代码工程,将来同时部署到多个设备

二、为了解决什么问题?

页面适配问题:界面级一多(重点掌握)
功能兼容问题:功能级一多(了解)
工程如何组织:工程级一多(重点掌握)

三、我们要掌握哪些知识、能力?

上面的3个问题,我们需要重点掌握页面适配问题和工程如何组织的问题,下面讲一页面适配问题的解决路径:界面级一多能力。
界面级一多能力有 2 类:

1.自适应布局: 略微调整界面结构
2.响应式布局:比较大的界面调整

用白话说,就是在格局较小变化的设备中,使用自适应布局;而在多终端切换的情况下使用响应式布局。

其中,自适应布局能力有以下几种:
在这里插入图片描述

布局能力有:拉伸能力、均分能力、占比能力、缩放能力、延伸能力、隐藏能力、折行能力。
而响应式布局会根据设备显示器的大小,预先设置不同的取值范围对应不同的断点,适用于不同类型的设备。设计思路举例如下:
在这里插入图片描述

四、自适应布局的七种布局能力

(一)拉伸能力

正常未拉伸状态:
在这里插入图片描述

极限压缩状态:
在这里插入图片描述

极限拉伸状态:
在这里插入图片描述

同时使用拉伸和放大能力:
在这里插入图片描述

上述案例中使用的就是拉伸能力的自适应的布局方式: 实际上,拉伸能力包含压缩和拉伸两种能力
在拉动下方的Slider滑动条时,我们会发现,左、中、右的大小都会随之变化。 那么变化的规律是什么?是怎么使其变化的呢?
首先,我们要知道这个案例的关键参数。 ① containerWidth =
600,这个是绑定的默认宽度,即左、中、右没有压缩也没有拉伸时的正常宽度。
②使用Builder建立的滑动条,设置了最小值和最大值的参数,分别是400和1000,这在后面会用来条件拉伸的比率。
其次,我们要知道这个案例使用了什么调试方法。
调试时,使用一个大的盒子,设定宽度width(this.containerWidth),其后的参数为@State标签修饰的变量,这个变量即Slilder滑动条组件的value值,使用双向绑定实时同步数值,预设值为600。在这个盒子中装入需要压缩、拉伸的小盒子。
在拉伸能力中用到的是flexShrink(压缩)和flexGrow(拉伸)两个属性,其后带的参数表示了压缩和拉伸的比例。(实践表明,调节其后的参数对实际的拉伸比例影响不大)
第三,极限压缩状态:中间的绿色方块,设定为宽300,高400,在横屏显示时可见其最小的状态是在压缩至极限时,此时的状态即为其所在的Row容器的设定大小(宽300,高400)。而两边的土灰色盒子则被压缩至大约原大小的三分之一左右。
第四,极限拉伸状态:两边的土灰色盒子的大小如其预先设定所在的Row容器大小一致(宽150,高400),而中间的绿色方块则被拉伸至最大,达到宽度约1000的大小。
小结:在上述操作中: (1)压缩和放大的比例不好准确推断,最好需要手动调试确认。
(2)但有一些可以提前确认的参数标准,即最大和最小的形状大小范围。 (3)拉伸能力所带的参数作用方式有待研究,但有时改变参数似乎影响不大。
(4)拉伸方法造成的图形大小会超出边框范围。
(5)收缩时,拉伸方法所在图形的大小不会小于原设定大小,放大时,收缩方法所在图形的大小不会大于原设定大小。(同一组件只使用压缩、放大一种能力)
(6)同一组件可以同时使用压缩、放大功能。

案例源码:

@Entry
@Component
struct Demo01 {
  // 绑定的宽度-默认 600
  @State containerWidth: number = 600
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸。
  @Builder
  sliderBuilder() {
    Slider({
      value: $$this.containerWidth, // 绑定的值
      min: 400, // 最小值
      max: 1000, // 最大值
      style: SliderStyle.OutSet // 滑块在滑轨上
    })
      .blockColor(Color.White)
      .width('60%')
      .position({ x: '20%', y: '80%' })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      // 标记现在的宽度
      Text('宽度:' + this.containerWidth)
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
​
      // 核心区域
      Column() {
        Column() {
          Row() {
            // 布局能l力 1:拉伸能力:
            // 容器组件尺寸发生改变时,将变化的部分分配给容器内的【指定区域】
            //
​
            // 涉及属性:
            // flexShrink:压缩比例,默认值:Column,Row 时(0),Flex 时(1)
            // flexGrow:拉伸比例,默认值 0
​
            // 需求:
            // 1. 空间不足时:分配给左右,1:1
            // 2. 空间富余时:分配给中间
​
            // 左
            Row() {
              Text('左')
                .fontSize(20)
                .fontColor(Color.White)
            }
            .justifyContent(FlexAlign.Center)
            .width(150)
            .height(400)
            .backgroundColor('#c2baa6')
            .flexShrink(1)
​
            // 中
            Row() {
              Text('中')
                .fontSize(30)
                .fontColor(Color.White)
            }
            .width(300)
            .height(400)
            .backgroundColor('#68a67d')
            .justifyContent(FlexAlign.Center)
            .flexGrow(1)
            //.flexShrink(1) //可同时使用压缩、拉伸能力
​
​
            // 右
            Row() {
              Text('右')
                .fontSize(20)
                .fontColor(Color.White)
            }
            .justifyContent(FlexAlign.Center)
            .width(150)
            .height(400)
            .backgroundColor('#c2baa6')
            .flexShrink(1)
          }
          .width(this.containerWidth)
          .justifyContent(FlexAlign.Center)
          .alignItems(VerticalAlign.Center)
          .border({ width: 2, color: Color.Orange })
          .backgroundColor(Color.Black)
        }
​
        // 底部滑块
        this.sliderBuilder()
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
    }
  }
}

应用场景联想: 拉伸能力的应用场景可放在:
(1)在线绘图工具:初始设定一定的图形大小,之后可在原先图形的基础上拉动压缩、拉伸其大小,可以对单一图形进行压缩拉伸,也可以对组合的图形统一进行压缩、拉伸
(2)可以用在图片处理工具中:用于图片大小的比例调节、图片的缩放等

(二)均分能力

指容器组件尺寸发生变化时,增加或减小的空间均匀分配给容器组件内所有【空白区域】。 常用于内容数量固定、均分显示的场景,比如工具栏、底部菜单栏、导航栏等。
在这里插入图片描述

如上图所示,这是一个由四个宽度分别为80的小组件组成的四个菜单按钮,总宽度320。

我们使用Row、Column、Flex等组件的 justifyContent (内容调整)属性进行自适应均分对齐
只需要将 justifyContent 后带的参数设置为FlexAlign.SpaceEvenly即可。
在这里插入图片描述

知识补充:
justifyContent()属于线性布局中典型的主轴对齐方式,其与FlexAlign枚举类型参的配合,有以下典型用法,均分布局是其中一种:

在这里插入图片描述

案例源码:

export interface NavItem {
  id: number
  icon: ResourceStr
  title: string
}
​
@Entry
@Component
struct Demo02 {
  readonly list: NavItem [] = [
    { id: 1, icon: $r('app.media.ic_nav_01'), title: '淘金币' },
    { id: 2, icon: $r('app.media.ic_nav_02'), title: '摇现金' },
    { id: 3, icon: $r('app.media.ic_nav_03'), title: '闲鱼' },
    { id: 4, icon: $r('app.media.ic_nav_04'), title: '中通快递' },
  ]
  @State rate: number = 600
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸
  @Builder
  sliderBuilder() {
    Slider({
      value: $$this.rate,
      min: 200,
      max: 600,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
​
      .position({ x: '20%', y: '80%' })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      // 标记现在的宽度
      Text('宽度:' + this.rate.toFixed(0))
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
​
      Column() {
        Column() {
          // 布局能力 2:均分能力
          // 指容器组件尺寸发生变化时,增加或减小的空间均匀分配给容器组件内所有【空白区域】。
          // 常用于内容数量固定、均分显示的场景,比如工具栏、底部菜单栏、导航栏等
​
          // 涉及属性:
          // Row、Column、Flex 组件的 justifyContent 属性
          // justifyContent设置为 FlexAlign.SpaceEvenly即可
          Row() {
            ForEach(this.list, (item: NavItem) => {
              Column() {
                Image(item.icon)
                  .width(48)
                  .height(48)
                  .margin({ top: 8 })
                Text(item.title)
                  .width(64)
                  .height(30)
                  .lineHeight(15)
                  .fontSize(12)
                  .textAlign(TextAlign.Center)
                  .margin({ top: 8 })
                  .padding({ bottom: 15 })
              }
              .width(80)
              .height(102)
              .backgroundColor('#8FBF9F')
              .borderRadius(10)
            })
          }
          .width('100%')
​
          .justifyContent(FlexAlign.SpaceEvenly) // 均分
​
        }
        .width(this.rate) // 绑定滑块改变的尺寸
        .padding({ top: 16 })
        .backgroundColor('#FFFFFF')
        .borderRadius(16)
​
​
        this.sliderBuilder()
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
    }
  }
}

小结: 1、均分能力自适应的使用要件:
(1)线性布局的均分布局方式
(2)有大小会变化的外部容器
2、使用场景:

常用于内容数量固定、均分显示的场景,比如工具栏、底部菜单栏、导航栏等

(三)占比能力

在这里插入图片描述
在这里插入图片描述

占比能力的使用很简单,主要是使用layoutWeight来调整需要自适应的组件的相对于上一级容器大小的占比参数,本例中,左、中、右三个播放按钮的占比比例均设为5,实质就是1:1:1,三个大小相同。这种情况下,仅需要设置layoutWeight比例,不需要设置实际的宽度值。
案例源码:

@Entry
@Component
struct Demo03 {
  @State rate: number = 200
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸
  @Builder
  slider() {
    Slider({
      value: $$this.rate,
      min: 200,
      max: 500,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
      .height(50)
​
      .position({ x: '20%', y: '80%' })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      // 显示目前容器的宽度
      Text('宽度:' + this.rate.toFixed(0))
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
​
​
      Column() {
        // 布局能力 3:占比能力
        // 子组件的宽高按照预设的比例,随父容器组件发生变化
​
        // 实现方式:
        // 1. 子组件的【宽高】设置为父组件宽高的【百分比】
        // 2. 通过 layoutWeight 属性设置主轴方向【布局权重】(比例)
​
​
        // 容器 主轴横向
        Row() {
          // 上一首
          Column() {
            Image($r("app.media.ic_public_play_last"))
              .width(50)
              .height(50)
              .border({ width: 2 })
              .borderRadius(30)
              .padding(10)
​
          }
          .height(96)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .layoutWeight(5) // 设置子组件在父容器主轴方向的布局权重
​
​
          // 播放&暂停
          Column() {
            Image($r("app.media.ic_public_pause"))
              .width(50)
              .height(50)
              .border({ width: 2 })
              .borderRadius(30)
              .padding(10)
          }
          .height(96)
          .backgroundColor('#66F1CCB8')
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .layoutWeight(5) // 设置子组件在父容器主轴方向的布局权重
​
​
          // 下一首
          Column() {
            Image($r("app.media.ic_public_play_next"))
              .width(50)
              .height(50)
              .border({ width: 2 })
              .borderRadius(30)
              .padding(10)
          }
          .height(96)
          .justifyContent(FlexAlign.Center)
          .alignItems(HorizontalAlign.Center)
          .layoutWeight(5) // 设置子组件在父容器主轴方向的布局权重
​
        }
        .width(this.rate) // 绑定宽度给 容器
        .height(96)
        .borderRadius(16)
        .backgroundColor('#FFFFFF')
​
        // 调整宽度的滑块
        this.slider()
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
    }
  }
}

小结: 占比能力与均分能力有相近性,有时可以替代使用;
但均分能力更强强调间隙的大小相等。

(四)缩放能力

在这里插入图片描述

在缩放能力案例中
小猴子图片的大小是400400大小的PNG图片。
而模拟器提供的模拟手机的大小为1080
2340。
经过四中情况的分析可知,400*400像素的PNG图片,其400的大小并不是vp(virtualpixel虚拟像素)单位,也不是px(物理像素)单位,在图中,要使小猴子图片刚好占满屏幕,需要使用其外一层的容器,控制容器宽度大小为360vp时,正好占满屏幕没有图片边缘耗费。此时模拟器的宽度为1080,是360的三倍,正好满足vp和px的单位互换比例:3倍。

案例源码:

@Entry
@Component
struct Demo04 {
  @State sliderWidth: number = 400
  @State sliderHeight: number = 400
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸
  @Builder
  slider() {
​
    Slider({
      value: $$this.sliderHeight,
      min: 100,
      max: 400,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
      .height(50)
​
      .position({ x: '20%', y: '80%' })
​
    Slider({
      value: $$this.sliderWidth,
      min: 100,
      max: 400,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
      .height(50)
​
      .position({ x: '20%', y: '87%' })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Text('宽度:' + this.sliderWidth.toFixed(0) + ' 高度:' + this.sliderHeight.toFixed(0))
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
      Column() {
        // 动态修改该容器的宽高
        Column() {
          Column() {
            Image($r("app.media.avatar"))
              .width('100%')
              .height('100%')
          }
          // 布局能力 4:缩放能力
          // 子组件的宽高按照预设的比例,随容器组件发生变化,且变化过程中子组件的【宽高比】不变。
​
          // 实现方式:
          // 给子组件设置 aspectRatio即可 设置的值是 宽度/高度
          // .aspectRatio(1 / 4) // 固定 宽 高比 1等同于 1:1
          // .aspectRatio(1 / 2) // 固定 宽 高比 1等同于 1:1
          .aspectRatio(1) // 宽高比为1:1
          .border({ width: 2, color: "#66F1CCB8" }) // 边框,仅用于展示效果
        }
        .backgroundColor("#FFFFFF")
        .height(this.sliderHeight)
        .width(this.sliderWidth)
        .justifyContent(FlexAlign.Center)
        .alignItems(HorizontalAlign.Center)
​
        this.slider()
      }
      .width('100%')
      .height('100%')
      .backgroundColor(Color.Blue)
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
    }
  }
}

(五)延伸能力

在延伸能力中,我们可以使用两种组件进行操作,一是List组件,二是Scroll组件,这两中组件都可以实现长度大于外部容器的元素的折叠表示,其中被折叠部分的元素,通过左右(或上下)拉动,均可实现滚动显示。

第二张图展示了滚动显示的状态。

第三张图展示了外容器大小大于内部元素,此时延伸到最大,无需再进行延伸、无法再进行滑动。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

案例源码:

import { NavItem } from './Demo02'
​
@Entry
@Component
struct Demo05 {
  @State rate: number = 100
  // 数组
  readonly appList: NavItem [] = [
    { id: 1, icon: $r('app.media.ic_nav_01'), title: '淘金币' },
    { id: 2, icon: $r('app.media.ic_nav_02'), title: '摇现金' },
    { id: 3, icon: $r('app.media.ic_nav_03'), title: '闲鱼' },
    { id: 4, icon: $r('app.media.ic_nav_04'), title: '中通快递' },
    { id: 5, icon: $r('app.media.ic_nav_05'), title: '芭芭农场' },
    { id: 6, icon: $r('app.media.ic_nav_06'), title: '淘宝珍库' },
    { id: 7, icon: $r('app.media.ic_nav_07'), title: '阿里拍卖' },
    { id: 8, icon: $r('app.media.ic_nav_08'), title: '阿里药房' },
  ]
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸
  @Builder
  slider() {
    Slider({
      value: $$this.rate,
      min: 100,
      max: 730,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
      .height(50)
​
      .position({ x: '20%', y: '80%' })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      // 展示宽度
      Text('宽度:' + this.rate.toFixed(0))
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
​
      Column() {
        Row({ space: 10 }) {
          // 布局能力 5:延伸能力
          // 容器组件内的子组件,按照其在列表中的先后顺序,随容器组件尺寸变化【显示或隐藏】
​
          // 实现方式:
          // 1.List 组件
          // 2.Scroll 配合 Row 或者 Column
          // 核心:调整父容器的尺寸,让页面中显示的组件数量发生改变
​
          // 通过Scroll 组件实现隐藏能力
          Scroll() {
            Row({ space: 10 }) {
              ForEach(this.appList, (item: NavItem, index: number) => {
                Column() {
                  Image(item.icon)
                    .width(48)
                    .height(48)
                    .margin({ top: 8 })
                  Text(item.title)
                    .width(64)
                    .height(30)
                    .lineHeight(15)
                    .fontSize(12)
                    .textAlign(TextAlign.Center)
                    .margin({ top: 8 })
                    .padding({ bottom: 15 })
                }
                .width(80)
                .height(102)
              })
            }
          }
          .scrollable(ScrollDirection.Horizontal) // 设置横向滚动
          .padding({ top: 16, left: 10 })
          .height(118)
          .borderRadius(16)
          .backgroundColor(Color.White)
        }
        .width(this.rate)
​
        this.slider()
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#F1F3F5')
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
    }
  }
}

(六)隐藏能力

容器组件内的子组件,按照其预设的显示优先级,随容器组件尺寸变化显示或隐藏 效果近似if else 条件渲染 适合管理多个组件 主要使用displayPriority属性,设置若干个优先级不同的单个组件
在这里插入图片描述

@Entry
@Component
struct Demo06 {
  @State rate: number = 48
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸
  @Builder
  slider() {
    Slider({
      value: $$this.rate,
      min: 80,
      max: 400,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
      .height(50)
​
      .position({ x: '20%', y: '80%' })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Text('宽度:' + this.rate.toFixed(0))
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
​
      Column() {
        // 布局能力 6:隐藏能力
        // 容器组件内的子组件,按照其预设的显示优先级,随容器组件尺寸变化显示或隐藏
        // if else 条件渲染 适合管理多个组件{多个组件}
        // displayPriority属性 适合设置若干个优先级不同的单个组件
​
​
        // 实现方式:
        // displayPriority属性:设置布局优先级来控制显隐
        // 当主轴方向剩余尺寸不足以满足全部元素时,按照布局优先级,从[小到大]依次隐藏
​
​
        Row({ space: 10 }) {
          Image($r("app.media.ic_public_favor"))
            .width(48)
            .height(48)
            .displayPriority(1) // 布局优先级
​
          Image($r("app.media.ic_public_play_last"))
            .width(48)
            .height(48)
            .displayPriority(2) // 布局优先级
​
          Image($r("app.media.ic_public_pause"))
            .width(48)
            .height(48)
            .displayPriority(3) // 布局优先级
​
          Image($r("app.media.ic_public_play_next"))
            .width(48)
            .height(48)
            .objectFit(ImageFit.Contain)
            .displayPriority(2) // 布局优先级
​
          Image($r("app.media.ic_public_view_list"))
            .width(48)
            .height(48)
            .objectFit(ImageFit.Contain)
            .displayPriority(1) // 布局优先级
        }
        .width(this.rate)
        .height(96)
        .borderRadius(16)
        .backgroundColor('#FFFFFF')
        .justifyContent(FlexAlign.Center)
        .padding(10)
​
        this.slider()
      }
      .width('100%')
      .height('100%')
      .backgroundColor(Color.Red)
      .justifyContent(FlexAlign.Center)
      .alignItems(HorizontalAlign.Center)
    }
​
  }
}

(七)折行能力

容器组件尺寸发生变化,当布局方向尺寸不足以显示完整内容时自动换行。
使用Flex组件将 wrap参数 设置为FlexWrap.Wrap即可。
在这里插入图片描述

import { NavItem } from './Demo02'
​
@Entry
@Component
struct Demo07 {
  @State rate: number = 0.7
  readonly imageList: NavItem [] = [
    { id: 1, icon: $r('app.media.ic_nav_01'), title: '淘金币' },
    { id: 2, icon: $r('app.media.ic_nav_02'), title: '摇现金' },
    { id: 3, icon: $r('app.media.ic_nav_03'), title: '闲鱼' },
    { id: 4, icon: $r('app.media.ic_nav_04'), title: '中通快递' },
    { id: 5, icon: $r('app.media.ic_nav_05'), title: '芭芭农场' },
    { id: 6, icon: $r('app.media.ic_nav_06'), title: '淘宝珍库' },
  ]
​
  // 底部滑块,可以通过拖拽滑块改变容器尺寸
  @Builder
  slider() {
    Slider({
      value: this.rate * 100,
      min: 10,
      max: 100,
      style: SliderStyle.OutSet
    })
      .blockColor(Color.White)
      .width('60%')
      .position({ x: '20%', y: '87%' })
      .onChange((value: number) => {
        this.rate = value / 100
      })
  }
​
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Text('宽度:' + (this.rate * 100).toFixed(0) + '%')
        .zIndex(2)
        .translate({ x: 20, y: 20 })
        .fontColor(Color.Orange)
      Flex({ justifyContent: FlexAlign.Center, direction: FlexDirection.Column }) {
        Column() {
          // 布局能力 7:折行能力
          // 容器组件尺寸发生变化,当布局方向尺寸不足以显示完整内容时自动换行
​
          // 实现方式:
          // Flex组件将 wrp 设置为FlexWrap.Wrap即可
​
​
          // 通过Flex组件warp参数实现自适应折行
          Flex({
            direction: FlexDirection.Row,
            alignItems: ItemAlign.Center,
            justifyContent: FlexAlign.Center,
            wrap: FlexWrap.Wrap // 是否换行:  FlexWrap.Wrap 开启换行
          }) {
            ForEach(this.imageList, (item: NavItem) => {
              Column() {
                Image(item.icon)
                  .width(80)
                  .height(80)
                Text(item.title)
              }
              .margin(10)
​
            })
          }
          .backgroundColor('#FFFFFF')
          .padding(20)
          .width(this.rate * 100 + '%')
          .borderRadius(16)
​
        }
        .width('100%')
​
        this.slider()
      }
      .width('100%')
      .height('100%')
      .backgroundColor(Color.Red)
    }
​
  }
}

五、总结

以上即一多开发中常用的七种自适应能力的总结。七种自适应能力分别是:拉伸能力、均分能力
、占比能力、缩放能力、延伸能力、隐藏能力、折行能力。

写在最后

有很多小伙伴不知道该从哪里开始学习鸿蒙开发技术?也不知道鸿蒙开发的知识点重点掌握的又有哪些?自学时频繁踩坑,导致浪费大量时间。结果还是一知半解。所以有一份实用的鸿蒙(HarmonyOS NEXT)全栈开发资料用来跟着学习是非常有必要的。

获取完整版高清学习资料,请点击→鸿蒙全栈开发学习资料(安全链接,请放心点击)

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了

最新鸿蒙全栈开发学习线路在这里插入图片描述

鸿蒙HarmonyOS开发教学视频

在这里插入图片描述

大厂面试真题

在这里插入图片描述

在这里插入图片描述

鸿蒙OpenHarmony源码剖析

在这里插入图片描述

这份资料能帮住各位小伙伴理清自己的学习思路,更加快捷有效的掌握鸿蒙开发的各种知识。有需要的小伙伴自行领取,,先到先得~无套路领取!!

获取这份完整版高清学习资料,请点击→鸿蒙全栈开发学习资料(安全链接,请放心点击)

  • 14
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值