Logo9 Patch Editor

如何在 Flutter 中使用点 9 图

2025年1月13日

点 9 图(Nine-patch image)是一种特殊的 PNG 图像,它允许开发者在拉伸图像时保持图像的某些区域不变形,从而避免图像失真。这在创建可缩放的 UI 元素(例如按钮背景、进度条等)时非常有用。虽然 Flutter 本身并不直接支持点 9 图的原生格式,但我们可以通过一些技巧来实现类似的效果。

使用 9 Patch Editor 创建点 9 图

首先,你需要准备一张 PNG 图片。然后,使用 9 Patch Editor 工具来创建你的点 9 图。该工具允许你指定图像的可拉伸区域和内容区域。具体操作步骤如下:

  1. 前往 9 Patch Editor 的网站。
  2. 上传你的 PNG 图片。
  3. 使用工具提供的编辑器,选择图像的可拉伸区域(拖动图像的左边缘和上边缘)。
  4. 选择图像的内容区域(拖动图像的右边缘和下边缘,这些区域在拉伸时保持不变)。
  5. 下载生成的点 9 图(请根据您的方案下载不同的图像)。

在 Flutter 中使用点 9 图

Flutter 没有直接加载点 9 图的机制。我们需要借助第三方库或者使用 Flutter 内置的Image.centerSlice属性来模拟点 9 图的效果。

方法一:使用第三方库

目前有一些 Flutter 的第三方库可以帮助你加载和渲染点 9 图,例如 ninepatch_imagenine_patch

使用 ninepatch_image 库

你需要在pubspec.yaml文件中添加依赖:

dependencies:
  ninepatch_image: ^0.0.4

将 PNG 图片放在你的 Flutter 项目的 assets 文件夹中,并在 pubspec.yaml 文件中声明:

flutter:
  assets:
    - assets/my_image.9.png

然后,你可以使用 NinePatchImage 小部件来显示你的点 9 图:

NinePatchImage(
  imageProvider: AssetImage("assets/my_image.9.png"),
  child: Text( "Lorem Ipsum is simply dummy text of the printing "))

详细的使用方法,请参考 ninepatch_image 的文档。

使用 nine_patch 库

你需要在pubspec.yaml文件中添加依赖:

dependencies:
  nine_patch: ^1.0.0

你需要在 assets 文件夹中创建一个存储点 9 图信息的 JSON 文件并将原图放在 assets 文件夹中。

assets/TextBox_Side.9.jsonassets/2.0x/TextBox_Side.png
(without the 1 pixel border)
{
  "stretch": {
    "x": 118,
    "y": 40,
    "width": 121,
    "height": 60
  },
  "contents": {
    "x": 19,
    "y": 18,
    "width": 248,
    "height": 101
  },
  "dimensions": {
    "x": 285,
    "y": 167
  },
  "name": "TextBox_Side.png",
  "scale": 2
}

Example nine-patch PNG file named TextBox_Side.png

stretch 是图像的可拉伸区域,contents 是图像的内容区域,dimensions 是图像的尺寸。您可以在 9 Patch Editor 工具中查看这些信息或者使用 nine_patcher 工具来生成这些信息。

然后,你可以使用 NinePatchImage 小部件来显示你的点 9 图:

import 'package:nine_patch/nine_patch.dart';

...

// Create a new NinePatchImage widget
NinePatchImage.fromAssetMetadata(
    name: "my_image.9.json",
)

记住将 assets/my_image.9.json 替换成你的点 9 图的 JSON 文件路径。

详细的使用方法,请参考 nine_patch 的文档。

方法二:使用 Image.centerSlice

如果你不想使用第三方库,可以使用 Flutter 内置的 Image.centerSlice 属性来模拟点 9 图的效果。 你需要手动指定图像的可拉伸区域:

Image.asset(
  'assets/my_image.png',
  width: 200,
  height: 100,
  centerSlice: Rect.fromLTWH(20, 20, 160, 60), // 手动指定可拉伸区域
),

注意:图片要使用原图编译后的图片

你需要根据你的图片手动调整 centerSlice 属性的值。你可以在 9 Patch Editor 工具中查看这些信息。

总结

虽然 Flutter 没有直接支持点 9 图,但我们可以通过使用第三方库或 Image.centerSlice 属性来实现类似的效果。推荐使用 ninepatch_image库,它使用起来更简单。如果你需要要更灵活和强大的功能,可以考虑使用 nine_patch。如果你不想引入第三方库,则可以使用 Image.centerSlice 方法,但功能有限,需要手动指定可拉伸区域。选择哪种方法取决于你的具体需求和项目复杂度。