HarmonyOS 鸿蒙Next支持类似Android的 .9图片吗?

HarmonyOS 鸿蒙Next支持类似Android的 .9图片吗? HarmonyOS支持类似Android的 .9图片吗? Image组件有没有提供相同功能的Api

4 回复

【背景知识】

Image是图片组件,常用于在应用中显示图片。Image组件提供与点九图相同功能的API设置,通过设置resizable属性来配置ResizableOptions,即图像拉伸时的大小调整选项。ResizableOptions的参数slice包含top、left、bottom和right四个属性,分别表示图片在上下左右四个方向拉伸时保持不变的距离。

【解决方案】

  • 通过调整Image中的width和height来将文字放到想要的图片中的位置,通过resizable属性,设置ResizableOptions参数,设置拉伸时上下左右距离一致,实现.9图。 代码如下:
import { MeasureText } from '@kit.ArkUI'

@Component
export struct CommonStyle {
  @Prop text: string = '';
  @State left: number = 10;
  @State right: number = 10;
  @State top: number = 10;
  @State bottom: number = 10;
  @State line: number = 2;
  @State textSize: SizeOptions = MeasureText.measureTextSize({ textContent: this.text });

  build() {
    Stack() {
      Image($r("app.media.11"))
        .width(px2vp(Number(`${this.textSize.width}`)) < 350 ? 60 + px2vp(Number(`${this.textSize.width}`)) : 380)
        .height(this.text.length < 40 ? 50 + px2vp(Number(`${this.textSize.height}`)) :
          50 + (px2vp(Number(`${this.textSize.height}`)) * this.line))
        .resizable({
          slice: {
            top: this.top,
            left: this.left,
            bottom: this.bottom,
            right: this.right
          }
        })
      Text(this.text)
        .fontColor(Color.White)
    }
    .width(350)
    .height(200)
  }
}
@Entry
@Component
struct ChatBubbleStretchDemo {
  build() {
    Column() {
      CommonStyle({ text: '一行文字' })
      CommonStyle({ text: '两行文字两行文字两行文字两行文字两行文字两行文字' })
      CommonStyle({
        text: '多行文字多行文字多行文字多行文字多行文字多行文字多行文字多行文字多行文字多行文字多行文字多行文字'
      })
    }
    .backgroundColor(Color.White)
    .height('100%')
    .width('100%')
  }
}

更多关于HarmonyOS 鸿蒙Next支持类似Android的 .9图片吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


【问题解析】

根据你的问题,其实就是设置图片拉伸区域的问题,本人前几天正好刚把这里整明白,可以把我的经验分享给你

【解决方案】

拉伸区域设置也分为多种情况:一种是无需拉伸边缘的(比较简单),另一种是冻结中间区域让边缘进行拉伸。

其实要实现相关功能就是Image组件中提供的.resizable(value: ResizableOptions)设置项。问题重点就在ResizeOptions上面,经过个人反复验证实验,发现官网给出的一些内容都存在不足,下面给你进行详细经验分享:

1、首先是简单的方法,通过ResizableOptions中的slice参数,这个参数类型是EdgeWidths,设置边缘宽度来固定该区域不被拉伸,分别为上下左右四个参数,此处引用官方图示:

图示

比如设置了相关参数,那么图片的1、2、3、4区域则不会被拉伸。

注意:此处需要根据图片组件的宽高(vp)进行设置,这里设置的相关参数就和设置padding一个原理(可以理解为给图片设置一个padding区域,这个区域内容不会被拉伸),和后面要讲的另一个方法完全不同。

2、如果你是要固定图片的中间区域,那么恭喜你,难度超大,但被我用三天时间摸透了,分享给你。若想固定图片中间区域,那显而易见上面的方法就失效了,则需要采取设置ResizableOptions中的lattice参数,这个参数类型是DrawingLattice,也就是需要自己去绘制网格,然后绘制的网格中偶数行和偶数列的内容不会被拉伸,如果去看官方文档说明,这里非常迷糊,直接听我讲吧。

首先了解绘制矩形网格对象,示例代码如下:

import { RenderNode } from '@kit.ArkUI';
import { drawing } from '@kit.ArkGraphics2D';

class DrawingRenderNode extends RenderNode {
  draw(context : DrawContext) {
    let xDivs : Array<number> = [1, 2, 4];
    let yDivs : Array<number> = [1, 2, 4];
    let lattice = drawing.Lattice.createImageLattice(xDivs, yDivs, 3, 3); // 划分(3+1)*(3+1)的网格,下图蓝色填充矩形为固定网格
  }
}

图示

当时我就是被这一段内容绕进去了,根据上述示例,会以为是绘制后的灰色区域会被冻结拉伸(因为resize配置项处的文档说是偶数行和列不会被拉伸),于是反复尝试反复尝试,发现是很多问题导致的错误。

1、上述代码中的偶数空间区域不会被拉伸(而不是图片中的偶数行列不被拉伸),如[1,2,4]其实指的是2到4之间区域不会被拉伸。

2、上面的1、2、4这些参数并不是像layoutweight那样按比例划分的,这些1、2、4代表的是图片以左上角为原点的x/y轴上的图片对应刻度参数。

3、你以为这就就结束了,其实这里还有一个问题就是,这里的单位是px,而不是方法1中的vp,更重要的是这里是通过图片的数据源像素来的,也不是方法一中的组件宽高(自己设置多少就是多少),因此使用此方法还需要先获取到图片源文件的像素值,后面才能再去做区域划分。

可能看到我总结的这些,你会觉得很容易,但这三个问题混到一起的时候真让人头疼,如果你要设置冻结中间某区域那就要认真看完这些。

以上就是我对该问题的讲解和经验,如有错误还望指正,如有不懂的地方可以继续回复,晚安!

鸿蒙Next支持.9图片格式。该格式在鸿蒙中称为九宫格图片,用于界面自适应布局。开发者可直接在鸿蒙项目中引入和使用.9图片资源,系统会自动处理拉伸区域与内容区域的适配。具体实现方式与Android类似,但需遵循鸿蒙的资源配置规范。

是的,HarmonyOS Next支持类似Android .9图片的功能,称为“九宫格拉伸”(NinePatch)。在HarmonyOS中,可以通过ohos.media.image相关API实现图片的可拉伸区域定义,避免缩放时失真。具体可使用PixelMapImage组件的属性来设置内容区域和拉伸区域,与Android .9图片原理一致。开发者文档中有详细说明,建议参考官方资源。

回到顶部