Добавление экрана загрузки в приложение React Native на iOS и Android
Экран загрузки React Native для iOS и Android: экран запуска в Xcode, темы и макеты для Android, а также библиотека react-native-splash-screen для устранения белого всплеска.
Источники: How to Add a Splash Screen to a React Native App (iOS and Android)
Чтобы выложить приложение React Native в магазины, необходимо сделать гораздо больше, чем просто его создать. До рассмотрения заявки требуются иконки, описания и экран загрузки, причем именно при создании экрана загрузки вступает в игру нативный код. Приведённые ниже шаги охватывают iOS и Android в их платформенных средах разработки с небольшим количеством нативного кода. Инструкции основаны на версии react-native-splash-screen (версия 3.0.6 и команда react-native link), поэтому более новые версии React Native могут обрабатывать процесс связывания по-другому.
Проекты, созданные с помощью Expo или Create React Native App, не требуют всего этого, поскольку их собственная документация описывает экраны загрузки всего в нескольких строках.
Хорошей отправной точкой будет новый проект, например react-native init SplashExample. Перед внесением любых изменений поместите его под контроль версий, чтобы ошибки было легко откатить и чтобы было ясно, какие именно файлы затрагивает экран загрузки.
Проектирование ресурсов
Ранее использовался подход, при котором в качестве экрана загрузки применялось одно большое изображение, которое плохо масштабировалось при изменении разрешений экранов. Лучший вариант — начать с простого квадратного изображения, похожего на иконку приложения, по двум причинам.
- Это создаёт впечатление, что нажатая вами иконка увеличивается и заполняет весь экран, что делает переход более плавным.
- Это сохраняет простоту. Экран загрузки должен быть виден всего несколько миллисекунд, поэтому он не должен содержать информацию. В конце концов, это экран загрузки.
Экспортируйте квадратное изображение в трёх размерах: 200 пикселей для @1x, 400 пикселей для @2x и 600 пикселей для @3x.
Фон, делающий вспышки заметными
Если вы ранее пробовали использовать экран загрузки в React Native, возможно, вы замечали белый всплеск света перед появлением контента. На приложении с белым фоном это трудно заметить, но это всё равно раздражает. Чтобы избежать любых всплесков света, установите тёмный фон для демо-приложения: укажите цвет фона как #4F6D7A, цвет текста — как #F5FCFF, а также измените цвет текста в строке состояния на светлый, всё это в файле App.js.
iOS
Откройте проект в Xcode:
open ios/SplashExample.xcodeproj
Сначала добавьте изображение. В левом навигаторе перейдите к элементу SplashExample, затем снова к SplashExample, после чего выберите папку Images.xcassets и нажмите кнопку «+» во втором столбце навигатора. Дайте этому ресурсу имя SplashIcon. Поместите туда три изображения — Xcode автоматически присвоит каждому из них соответствующую плотность пикселей.
Далее откройте файл LaunchScreen.xib в левом навигаторе. В нем находятся два текстовых элемента: название проекта и текст «Powered by React Native». Выберите оба элемента и удалите их.
Установите фон для элемента View. Во втором навигаторе выберите элемент View, затем в правой панели выберите опцию Background, чтобы открыть выбрасыватель цветов. Совет, который требует некоторого времени, чтобы его обнаружить: выберите вторую вкладку в выбрасывателе, затем опцию «RGB Sliders» — появится поле для ввода шестнадцатеричного значения. Введите код #4F6D7A.
Теперь добавьте элемент Image View. Откройте библиотеку объектов (третья иконка в правом нижнем углу панели инструментов), найдите элемент «image» и перетащите Image View на цветную область отображения. В панели атрибутов в правом верхнем углу выберите SplashIcon в качестве изображения. Установите режим содержимого на «Aspect Fit», который находится вторым сверху в этой панели, чтобы пропорции оставались правильными.
Чтобы иконка оставалась центрированной на любом устройстве, откройте вкладку линейки (пятая иконка в верхней части правой панели). В поле Autoresizing отключите внешние красные линии и включите внутренние красные стрелки. Изображение будет оставаться центрированным независимо от размера экрана.
Таким образом получается экран загрузки, но белый всплеск всё ещё присутствует.
Почему появляется всплеск
При запуске приложения iOS сразу отображает экран загрузки. Затем React Native нуждается в времени на запуск: загружается JavaScript, и инициализируется мост связи. В течение этого периода нативный экран загрузки исчезает, и ничего ещё не отрендерено, поэтому вы видите белый фон. Решением является удержание экрана загрузки немного дольше, чем по умолчанию, пока JavaScript не будет готов. Для этого предназначена библиотека react-native-splash-screen.
Установите её и подключите:
yarn add react-native-splash-screen@3.0.6
react-native link react-native-splash-screen
Затем настройте сторону приложения для операционной системы. В Xcode откройте файл AppDelegate.m, добавьте импорт заголовочного файла пакета SplashScreen.h вместе с другими импортами и вызовите [SplashScreen show]; непосредственно перед строкой return YES; внутри метода didFinishLaunchingWithOptions.
Со стороны JavaScript сообщите экрану загрузки исчезнуть, как только приложение будет готово. Вызовите метод скрытия пакета из метода componentDidMount в файле App.js.
Результат выглядит хорошо, осталась лишь одна мелкая деталь: цвет полосы состояния во время отображения экрана загрузки. В файле Info.plist добавьте строку с ключом UIStatusBarStyle и строковым значением UIStatusBarStyleLightContent. После этого настройка для iOS завершена.
Android
В Android ситуация немного сложнее, так как требуются два отдельных экрана загрузки. Один из них принадлежит библиотеке react-native-splash-screen, а другой отображается до того, как приложение загружает свои элементы интерфейса.
Ресурсы
Скопируйте изображения в папки mipmap, расположенные внутри android/app/src/main/res. Android называет категории плотности иначе, чем iOS, поэтому файлы необходимо соотнести:
- В папку
mipmap-mdpiпомещается изображение в разрешении 1x. - В папку
mipmap-hdpi— изображение в разрешении 2x. - В папку
mipmap-xhdpi— изображение в разрешении 3x. - В папку
mipmap-xxhdpiтакже помещается изображение в разрешении 3x.
Внутри каждой папки переименуйте файл в icon.png.
Экран загрузки при первом запуске
Первый экран появляется, когда приложение запускается из состояния «холодного» старта. Этот подход основан на известной статье Big Nerd Ranch о правильном создании экранов загрузки, в которой более подробно объясняются принципы их реализации.
- Создайте файл
background_splash.xmlв папкеandroid/app/src/main/res/drawable. Вероятно, потребуется сначала создать папкуdrawable. В этом файле определяется структураlayer-list— стек слоев. Первый слой заполняется цветом фона (определенным далее), а второй отображает иконку размером 200dp в ширину и высоту, расположенную по центру. - Создайте файл
colors.xmlв папкеandroid/app/src/main/res/valuesи укажите цвет синего оттенка, тот же, что используется в приложении.
styles.xml, находящемся в той же папке, определите тему SplashTheme. Она использует background_splash в качестве фона окна и синий цвет для полосы состояния, что максимально точно воспроизводит реальное приложение, включая изменение цвета полосы состояния. Также убедитесь, что цвет полосы состояния по умолчанию установлен правильно.AndroidManifest.xml укажите, чтобы приложение сначала использовало тему SplashTheme. Внутри тега <application> зарегистрируйте новый класс SplashActivity в качестве запускающего элемента, а также скорректируйте класс MainActivity, чтобы он больше не использовался в качестве запускающего элемента. Обратите внимание на параметр android:exported="true", который необходимо указать там, где требуется, в более новых версиях Android.SplashActivity.java. Его единственная задача — немедленно перенаправить пользователя в класс MainActivity, который представляет собой само приложение React Native.Запустите приложение, закройте его, чтобы следующий запуск прошел с нуля, затем снова откройте его. Экран загрузки появляется мгновенно, за ним следует тот же белый всплеск. Для устранения этой проблемы требуется немного больше усилий, чем в iOS, но не слишком много.
Удерживание экрана загрузки до готовности JavaScript
Если пакет еще не установлен, добавьте его и сделайте соответствующую ссылку:
yarn add react-native-splash-screen@3.0.6
react-native link
Настройте сторону Android, добавив вызов инициализации пакета в файл MainActivity.java. В файле App.js убедитесь, что экран загрузки закрывается сразу после загрузки приложения, как это делается в iOS.
Затем создайте файл launch_screen.xml в папке android/app/src/main/res/layout. Название имеет значение, поскольку библиотека ищет именно его. В качестве корневого элемента используйте LinearLayout. В Android Studio есть визуальный редактор, похожий на Interface Builder в Xcode, но здесь проще редактировать XML напрямую. Установите параметр gravity для макета как center, а фон — в синий цвет, оставив остальные параметры по умолчанию. Внутри добавьте элемент ImageView, который будет отображать иконку.
Параметры элемента ImageView:
- Параметры
android:layout_widthиandroid:layout_heightзадают размер, соответствующий размеру, используемому в файлеbackground_splash.xml.
android:layout_marginTop должен соответствовать высоте полосы статуса. Если его не указать, иконка будет располагаться в немного другом месте по сравнению с первым экраном загрузки, что приведёт к заметному смещению при замене одного экрана другим.android:src="@mipmap/icon" указывает на изображение.Наконец, в файле colors.xml требуется ещё одна запись:
<color name="primary_dark">#4F6D7A</color>
Если его пропустить, при запуске приложение вылетает. Причина — дефект в самом react-native-splash-screen, поэтому в более поздних версиях он может стать ненужным.
При наличии обоих компонентов приложение запускается с непрерывным экраном загрузки без мерцания как на iOS, так и на Android.