Изображения
Статические ресурсы изображений
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 вам, возможно, потребуется перезапустить сборщик модулей, если вы добавите новые изображения в свой проект.
Вот некоторые преимущества, которые вы получаете:
- Одинаковая система для Android и iOS.
- Изображения находятся в той же папке, что и ваш JavaScript-код. Компоненты самодостаточны.
- Нет глобального пространства имен, то есть вам не нужно беспокоиться о конфликтах имен.
- В ваше приложение будут упакованы только те изображения, которые фактически используются.
- Добавление и изменение изображений не требует перекомпиляции приложения, вы можете обновить эмулятор, как обычно.
- Сборщик модулей знает размеры изображения, нет необходимости дублировать их в коде.
- Изображения можно распространять через пакеты 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:' для использования этих изображений. Как и для ресурсов из сети, вам необходимо вручную указать размеры вашего изображения.
Это рекомендуется только для очень маленьких и динамических изображений, таких как значки в списке из базы данных.
// 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:
borderTopLeftRadiusborderTopRightRadiusborderBottomLeftRadiusborderBottomRightRadius
Декодирование вне потока
Декодирование изображения может занимать более одного кадра. Это одна из основных причин пропусков кадров в веб-приложениях, потому что декодирование выполняется в основном потоке. В 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