Как использовать Nine-patch изображения во Flutter

13 января 2025 г.

Nine-patch изображение — это особый вид PNG-изображения, который позволяет разработчикам сохранять неискаженными определенные области изображения при его растягивании, тем самым избегая искажения изображения. Это особенно полезно при создании масштабируемых элементов пользовательского интерфейса, таких как фон кнопок, индикаторы прогресса и т.д. Хотя Flutter сам по себе не поддерживает собственный формат nine-patch изображений, мы можем добиться аналогичного эффекта, используя некоторые хитрости.

Создание Nine-patch изображений с помощью 9 Patch Editor

Сначала вам нужно подготовить PNG-изображение. Затем используйте инструмент 9 Patch Editor для создания вашего nine-patch изображения. Этот инструмент позволяет вам указать области изображения, которые можно растягивать, и области содержимого. Конкретные шаги следующие:

  1. Перейдите на сайт 9 Patch Editor.
  2. Загрузите ваше PNG-изображение.
  3. Используя редактор инструмента, выберите области изображения для растягивания (перетащите левый и верхний края изображения).
  4. Выберите области содержимого изображения (перетащите правый и нижний края изображения, эти области останутся неизменными при растягивании).
  5. Загрузите созданное nine-patch изображение (пожалуйста, загрузите различные изображения в зависимости от вашего плана).

Использование Nine-patch изображений во Flutter

Flutter не имеет механизма для прямой загрузки nine-patch изображений. Нам нужно использовать сторонние библиотеки или использовать встроенное свойство Flutter Image.centerSlice, чтобы имитировать эффект nine-patch изображения.

Способ первый: использование сторонних библиотек

В настоящее время существует несколько сторонних библиотек Flutter, которые могут помочь вам загружать и рендерить nine-patch изображения, такие как ninepatch_image и nine_patch.

Использование библиотеки ninepatch_image

Вам нужно добавить зависимость в файл pubspec.yaml:

dependencies:
  ninepatch_image: ^0.0.4

Поместите PNG-изображение в папку assets вашего Flutter-проекта и объявите его в файле pubspec.yaml:

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

Затем вы можете использовать виджет NinePatchImage для отображения вашего nine-patch изображения:

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

Вам нужно создать JSON-файл, хранящий информацию о nine-patch изображении, в папке assets и поместить оригинальное изображение в папку assets.

assets/TextBox_Side.9.jsonassets/2.0x/TextBox_Side.png
(без границы в 1 пиксель)
{
  "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
}

Пример nine-patch PNG-файла с именем TextBox_Side.png

stretch - это область изображения для растягивания, contents - это область содержимого изображения, dimensions - это размеры изображения. Вы можете просмотреть эту информацию в инструменте 9 Patch Editor или использовать инструмент nine_patcher для генерации этой информации.

Затем вы можете использовать виджет NinePatchImage для отображения вашего nine-patch изображения:

import 'package:nine_patch/nine_patch.dart';

...

// Создать новый виджет NinePatchImage
NinePatchImage.fromAssetMetadata(
    name: "my_image.9.json",
)

Не забудьте заменить assets/my_image.9.json на путь к вашему JSON-файлу nine-patch изображения.

Подробную информацию о том, как использовать библиотеку, смотрите в документации к nine_patch.

Способ второй: использование Image.centerSlice

Если вы не хотите использовать сторонние библиотеки, вы можете использовать встроенное свойство Flutter Image.centerSlice для имитации эффекта nine-patch изображения. Вам нужно вручную указать область растягивания изображения:

Image.asset(
  'assets/my_image.png',
  width: 200,
  height: 100,
  centerSlice: Rect.fromLTWH(20, 20, 160, 60), // Вручную указать область для растягивания
),

Примечание: изображение должно быть оригинальным или скомпилированным изображением.

Вам нужно вручную настроить значения свойства centerSlice в соответствии с вашим изображением. Вы можете просмотреть эту информацию в инструменте 9 Patch Editor.

Заключение

Хотя Flutter не поддерживает напрямую nine-patch изображения, мы можем добиться аналогичного эффекта, используя сторонние библиотеки или свойство Image.centerSlice. Рекомендуется использовать библиотеку ninepatch_image, так как она проще в использовании. Если вам нужен более гибкий и мощный функционал, можно рассмотреть использование nine_patch. Если вы не хотите подключать сторонние библиотеки, вы можете использовать метод Image.centerSlice, но его функционал ограничен и требует ручного указания области растягивания. Выбор метода зависит от ваших конкретных потребностей и сложности проекта.