Spec-Zone.ru › React Native

Изображения

Статические ресурсы изображений

React Native предоставляет унифицированный способ управления изображениями и другими медиа-активами в ваших приложениях для Android и iOS. Чтобы добавить статическое изображение в ваше приложение, поместите его в вашу структуру исходного кода и ссылайтесь на него так:

<Image source={require('./my-icon.png')} />

Имя изображения разрешается так же, как модули JS. В приведенном выше примере сборщик модулей будет искать my-icon.png в той же папке, что и компонент, который его требует.

Вы можете использовать суффиксы @2x и @3x, чтобы предоставить изображения для различных разрешений экрана. Если у вас следующая структура файлов:

.
├── button.js
└── img
    ├── check.png
    ├── check@2x.png
    └── check@3x.png

...и в коде button.js содержится:

<Image source={require('./img/check.png')} />

...сборщик модулей будет собирать и предоставлять изображение, соответствующее разрешению экрана устройства. Например, check@2x.png, будет использоваться на iPhone 7, а check@3x.png — на iPhone 7 Plus или Nexus 5. Если нет изображения, соответствующего разрешению экрана, будет выбран ближайший подходящий вариант.

В Windows вам, возможно, потребуется перезапустить сборщик модулей, если вы добавите новые изображения в свой проект.

Вот некоторые преимущества, которые вы получаете:

  1. Одинаковая система для Android и iOS.
  2. Изображения находятся в той же папке, что и ваш JavaScript-код. Компоненты самодостаточны.
  3. Нет глобального пространства имен, то есть вам не нужно беспокоиться о конфликтах имен.
  4. В ваше приложение будут упакованы только те изображения, которые фактически используются.
  5. Добавление и изменение изображений не требует перекомпиляции приложения, вы можете обновить эмулятор, как обычно.
  6. Сборщик модулей знает размеры изображения, нет необходимости дублировать их в коде.
  7. Изображения можно распространять через пакеты npm.

Для работы имя изображения в require должно быть известно статически.

// GOOD
<Image source={require('./my-icon.png')} />;

// BAD
var icon = this.props.active
  ? 'my-icon-active'
  : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />;

// GOOD
var icon = this.props.active
  ? require('./my-icon-active.png')
  : require('./my-icon-inactive.png');
<Image source={icon} />;

Обратите внимание, что источники изображений, требуемые таким образом, включают информацию о размере (ширина, высота) для Image. Если вам нужно динамически изменять масштаб изображения (например, с помощью flex), вам может потребоваться вручную установить { width: undefined, height: undefined } в атрибуте стиля.

Статические ресурсы, не являющиеся изображениями

Синтаксис require выше также можно использовать для статической вставки аудио-, видео- или документов в ваш проект. Поддерживаются наиболее распространённые типы файлов, включая .mp3, .wav, .mp4, .mov, .html и .pdf. Полный список см. в значениях по умолчанию сборщика модулей.

Вы можете добавить поддержку других типов, добавив assetExts параметр разрешения в вашей конфигурации Metro.

Важно, что видео должны использовать абсолютное позиционирование вместо flexGrow, так как информация о размере в настоящее время не передаётся для ресурсов, не являющихся изображениями. Это ограничение не возникает для видео, которые связаны непосредственно с Xcode или папкой Assets для Android.

Изображения из ресурсов гибридного приложения

Если вы создаёте гибридное приложение (некоторые пользовательские интерфейсы на React Native, некоторые пользовательские интерфейсы в коде платформы), вы по-прежнему можете использовать изображения, которые уже включены в приложение.

Для изображений, включенных с помощью каталогов ресурсов Xcode или в папке drawable Android, используйте имя изображения без расширения:

<Image
  source={{ uri: 'app_icon' }}
  style={{ width: 40, height: 40 }}
/>

Для изображений в папке Android assets используйте схему asset:/.

<Image
  source={{ uri: 'asset:/app_icon.png' }}
  style={{ width: 40, height: 40 }}
/>

Эти подходы не предусматривают проверок безопасности. Вам нужно гарантировать, что эти изображения доступны в приложении. Также необходимо вручную указать размеры изображения.

Изображения из сети

Многие изображения, которые вы будете отображать в своем приложении, не будут доступны во время компиляции, или вы захотите загружать их динамически, чтобы уменьшить размер двоичного файла. В отличие от статических ресурсов, вам необходимо вручную указать размеры вашего изображения. Настоятельно рекомендуется использовать https, чтобы удовлетворить требования App Transport Security на iOS.

// GOOD
<Image source={{uri: 'https://reactjs.org/logo-og.png'}}
       style={{width: 400, height: 400}} />

// BAD
<Image source={{uri: 'https://reactjs.org/logo-og.png'}} />

Запросы изображений из сети

Если вы хотите настроить такие параметры, как HTTP-глагол, заголовки или тело вместе с запросом изображения, вы можете сделать это, определив эти свойства в объекте source:

<Image
  source={{
    uri: 'https://reactjs.org/logo-og.png',
    method: 'POST',
    headers: {
      Pragma: 'no-cache'
    },
    body: 'Your Body goes here'
  }}
  style={{ width: 400, height: 400 }}
/>

Изображения из данных URI

Иногда вы можете получать закодированные данные изображения из вызова REST-API. Вы можете использовать схему URI 'data:' для использования этих изображений. Как и для ресурсов из сети, вам необходимо вручную указать размеры вашего изображения.

info

Это рекомендуется только для очень маленьких и динамических изображений, таких как значки в списке из базы данных.

// include at least width and height!
<Image
  style={{
    width: 51,
    height: 51,
    resizeMode: 'contain'
  }}
  source={{
    uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='
  }}
/>

Управление кэшем (только iOS)

В некоторых случаях вы можете отображать изображение только в том случае, если оно уже находится в локальном кэше, например, низкокачественный заполнитель до тех пор, пока не станет доступным изображение более высокого качества. В других случаях вам не важно, устарело ли изображение, и вы готовы отображать устаревшее изображение, чтобы сэкономить трафик. Свойство source cache даёт вам контроль над тем, как сетевой уровень взаимодействует с кэшем.

  • default: Использовать стандартную стратегию родной платформы.
  • reload: Данные для URL будут загружены из исходного источника. Никакие данные из кэша не должны использоваться для удовлетворения запроса загрузки URL.
  • force-cache: Существующие данные кэша будут использоваться для удовлетворения запроса, независимо от его возраста или даты истечения срока действия. Если в кэше нет соответствующих данных запроса, данные загружаются из исходного источника.
  • only-if-cached: Существующие данные кэша будут использоваться для удовлетворения запроса, независимо от его возраста или даты истечения срока действия. Если в кэше нет соответствующих данных для запроса загрузки URL, попытка загрузить данные из исходного источника не предпринимается, и загрузка считается неудачной.
<Image
  source={{
    uri: 'https://reactjs.org/logo-og.png',
    cache: 'only-if-cached'
  }}
  style={{ width: 400, height: 400 }}
/>

Изображения из локальной файловой системы

См. CameraRoll для примера использования локальных ресурсов, которые находятся за пределами Images.xcassets.

Лучшее изображение из Camera Roll

iOS сохраняет несколько размеров для одного изображения в вашем Camera Roll, очень важно выбрать размер, максимально приближенный к нужному, по соображениям производительности. Вы не захотите использовать изображение с полным качеством 3264x2448 в качестве источника при отображении миниатюры 200x200. Если есть точное совпадение, React Native выберет его, в противном случае будет использоваться первое изображение, размер которого по крайней мере на 50% больше, чтобы избежать размытия при изменении размера с близкого размера. Всё это делается по умолчанию, поэтому вам не нужно беспокоиться о написании утомительного (и склонного к ошибкам) кода для этого.

Почему не масштабировать всё автоматически?

В браузере, если вы не укажете размер изображения, браузер отобразит элемент 0x0, загрузит изображение и затем отобразит его с правильным размером. Основная проблема с этим поведением заключается в том, что ваш пользовательский интерфейс будет прыгать во время загрузки изображений, что создаёт плохой пользовательский опыт.

В React Native это поведение намеренно не реализовано. Разработчикам необходимо знать размеры (или соотношение сторон) удалённого изображения заранее, но мы считаем, что это приводит к лучшему пользовательскому опыту. Статические изображения, загруженные из пакета приложения с помощью синтаксиса require('./my-icon.png'), могут быть автоматически масштабированы, поскольку их размеры доступны сразу при монтировании.

Например, результатом require('./my-icon.png') может быть:

{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}

Источник как объект

В React Native интересное решение заключается в том, что атрибут src называется source и принимает не строку, а объект со свойством uri.

<Image source={{ uri: 'something.jpg' }} />

На стороне инфраструктуры это позволяет нам прикрепить метаданные к этому объекту. Например, если вы используете require('./my-icon.png'), тогда мы добавляем информацию о его фактическом расположении и размере (не полагайтесь на этот факт, он может измениться в будущем!). Это также обеспечивает будущую совместимость, например, мы можем в какой-то момент добавить поддержку спрайтов. Вместо вывода {uri: ...}, мы можем вывести {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}} и прозрачно поддерживать спрайты на всех существующих местах вызова.

С точки зрения пользователя это позволяет вам добавлять полезные атрибуты, такие как размеры изображения, для вычисления размера, который будет отображён. Используйте его в качестве структуры данных для хранения большей информации об изображении.

Фоновое изображение через вложение

Часто запрашиваемая функция разработчиками, знакомыми с веб-технологиями, — background-image. Для обработки этого случая вы можете использовать компонент <ImageBackground>, который имеет те же свойства, что и <Image>, и добавить к нему любые дочерние элементы, которые вы хотите наложить поверх него.

Возможно, в некоторых случаях вы не захотите использовать <ImageBackground>, так как реализация очень простая. Для более глубокого понимания обратитесь к документации <ImageBackground> (документация) и создайте свой собственный пользовательский компонент, когда это необходимо.

return (
  <ImageBackground source={...} style={{width: '100%', height: '100%'}}>
    <Text>Inside</Text>
  </ImageBackground>
);

Обратите внимание, что вы должны указать атрибуты стиля width и height.

Стили радиуса границы iOS

Обратите внимание, что следующие свойства стилей радиуса границы, специфичные для углов, могут быть проигнорированы компонентом изображения iOS:

  • borderTopLeftRadius
  • borderTopRightRadius
  • borderBottomLeftRadius
  • borderBottomRightRadius

Декодирование вне потока

Декодирование изображения может занимать более одного кадра. Это одна из основных причин пропусков кадров в веб-приложениях, потому что декодирование выполняется в основном потоке. В React Native декодирование изображения выполняется в другом потоке. На практике вам уже нужно обрабатывать случай, когда изображение ещё не загружено, поэтому отображение заполнителя на несколько дополнительных кадров во время декодирования не требует никаких изменений в коде.

Настройка ограничений кэша изображений iOS

В iOS мы предоставляем API для переопределения стандартных ограничений кэша изображений React Native. Это должно вызываться в коде вашего native AppDelegate (например, в didFinishLaunchingWithOptions).

RCTSetImageCacheLimits(4*1024*1024, 200*1024*1024);

Параметры:

Имя Тип Обязательно Описание
imageSizeLimit число Да Предел размера кэша изображений.
totalCostLimit число Да Предел общей стоимости кэша.

В приведённом выше примере размер кэша изображения установлен в 4 МБ, а общий предел стоимости — 200 МБ.

© 2022 Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://reactnative.dev/docs/images

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API