Разработка React Native APP — начиная с преобразования официальной демоверсии (2)

React Native

через первую частьРазработка React Native APP — начиная с преобразования официальной демоверсии (1)Введение, основная конструкция платформы приложения завершена. В этой части в основном обсуждаются пользовательский интерфейс/взаимодействие, подготовка к выпуску приложения и способы его выпуска. Конкретное содержание включает:

  • Исходя из использования реактивной навигации,iOS реализует анимацию входа одной страницы снизу вверх (модально)
  • адаптивный размер
  • Установите начальную страницу, измените значок на рабочем столе, отображаемое имя приложения, идентификатор приложения
  • Пакетный выпуск

В этом полном демоreact-native-complete-demo

Навигация по расширению

Расширение здесь относится к реализацииСпособ входа на страницу можно настроить индивидуально(react navigationПо умолчанию поддерживается только глобальная конфигурация илиcard, илиmodal, после настройки все страницы будут иметь одинаковую анимацию).

Для достижения вышеуказанного эффекта необходимы две модификации:StackNavigatorAPI (вroute.jsиспользуется в) и вход на определенную страницу является методом вызова.

1.1 МодификацияStackNavigator API

После модификации, если состояние страницы по умолчанию — карточка, вам нужно только войти на соответствующую страницу, например..navigate('ScreenSome1'); Если вы хотите, чтобы страница входила как модальная, вам нужно всего лишь добавить модальный путь к пути. Например:..navigate('ScreenSome2Modal').

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

/**
 * route.js
 * 自定义 StackNavigator,可以选择 screen 进入方式
 */
const StackModalNavigator = (routeConfigs, navigatorConfig) => {
  const CardStackNavigator = StackNavigator(routeConfigs, navigatorConfig);
  const modalRouteConfig = {};
  const routeNames = Object.keys(routeConfigs);

  for (let i = 0; i < routeNames.length; i++) {
    modalRouteConfig[`${routeNames[i]}Modal`] = routeConfigs[routeNames[i]];
  }

  const ModalStackNavigator = StackNavigator(
    {
      CardStackNavigator: { screen: CardStackNavigator },
      ...modalRouteConfig
    },
    {
      // 如果页面进入方式为 modal,需要自定义 header(默认 header 样式失效,都叠在一块了)
      mode: "modal",
      headerMode: "none"
    }
  );

  return ModalStackNavigator;
};

// 设置路由
const AppNavigator = StackModalNavigator();

1.2 Вызов на странице

Сначала создаем новую страницуScreenSome2, то пусть входит в виде модального (заход снизу экрана), в качестве сравненияScreenSome1кcardформа для ввода (метод ввода по умолчанию, ввод с правой стороны экрана).

Поскольку страница, введенная в модальной форме, требует пользовательского заголовка, обычно это просто кнопка закрытия, чтобыScreenSome2Например:

/**
 * ScreenSome2/view.js
 * 自定义 header(关闭按钮)
 */
<View>
  {/* TouchableHighlight 为关闭按钮的热区 */}
  <TouchableHighlight
    onPress={() => self.navigation.goBack()}
    underlayColor="transparent"
    style={{
      display: "flex",
      justifyContent: "center",
      marginTop: pxToDp(30),
      width: pxToDp(150),
      height: pxToDp(90),
      backgroundColor: "yellow"
    }}
  >
    <Text style={{ marginLeft: pxToDp(24) }}>关闭</Text>
  </TouchableHighlight>

  <Text style={{ fontSize: pxToDp(36) }}>some2,以 modal 的形式进入</Text>
</View>

Затем измените наScreenSome2код, вотScreenHomeКод на странице:

/**
 * ScreenHome/view.js
 * 自定义 header(关闭按钮)
 */

{
  /* ScreenSome2 从屏幕右侧进入 */
}
<Button
  title="goSome1"
  onPress={() => self.navigation.navigate("ScreenSome1")}
/>;

{
  /* ScreenSome2 从屏幕下面进入 */
}
<Button
  title="goSome2Modal"
  onPress={() => self.navigation.navigate("ScreenSome2Modal")}
/>;

Финальные рендеры:

自定义页面进入动画

Два адаптивных

Адаптивный в основном включает в себя два аспекта: размер адаптируется в зависимости от размера экрана, в том числеfontSize,widthи т. д.; разрешение изображения является адаптивным в соответствии с разрешением экрана, что часто называют двойным изображением, тройным изображением и т. д.

2.1 Адаптация размера

Принцип адаптации размера заключается в том, чтобы получить ширину экрана мобильного телефона и соответствующим образом отрегулировать размер.Для этой цели функция инструмента инкапсулируется и помещается вconfig/pxToDp.jsсередина.

Содержание скорректировано следующим образом:

尺寸转换函数目录

  • config/pxToDp.jsВспомогательная функция для преобразования размера

Вспомогательная функция для преобразования размера находится в первой частиРазработка React Native APP — начиная с преобразования официальной демоверсии (1)уже добавлено

1) Напишите функцию инструмента с адаптивным размером

Поскольку все данные, включающие измерения, преобразуются (fontSize,widthд.), поэтому преобразованные данные необходимо обрабатывать, чтобы обеспечить: 1. числа, большие или равные 1, округляются в большую сторону; 2. числа меньше 1, если для платформы ios установлено значение 0,5; если для платформы Android равномерно установлено на 1 (поскольку разрешения платформ Android сильно различаются, экраны с низким разрешением отображают размер 0,5 с зубчатыми краями). Полный код функции инструмента выглядит следующим образом:

/**
 * pxToDp.js
 * 自适应布局
 * @param uiElementPx: ui给的原始尺寸
 */

import { Dimensions, Platform } from "react-native";

// app 只有竖屏模式,所以可以只获取一次 width
const deviceWidthDp = Dimensions.get("window").width;

// UI 默认给图是 750
const uiWidthPx = 750;

function pxToDp(uiElementPx) {
  const transferNumb = uiElementPx * deviceWidthDp / uiWidthPx;

  if (transferNumb >= 1) {
    // 避免出现循环小数
    return Math.ceil(transferNumb);
  } else if (Platform.OS === "android") {
    // 如果是安卓,最小为1,避免边框出现锯齿
    return 1;
  }
  return 0.5;
}

export default pxToDp;

Фактически, поDimensions.get('window').widthПолученная ширина экрана может отличаться от того, что вы себе представляли, например, если экран iphone7 4,7", полученная ширина равна375, Huawei P9 составляет 5,2 дюйма, но полученная ширина составляет360! Что-то вроде ямы, эту функцию инструмента еще нужно оптимизировать.

2) Используйте функцию инструмента адаптивного размера

Метод использования очень прост: ввести функцию инструмента для преобразования размера в компонент, который необходимо преобразовать в единицу измерения, и передать размер, который необходимо преобразовать, в функцию инструмента.ScreenHomeНапример:

/**
 * ScreenHome/view.js
 */

// 引入尺寸转换工具函数
import pxToDp from "../../config/pxToDp";

// 将需要转换的单位传入 pxToDp 中
<Text style={{ fontSize: pxToDp(36) }}>home</Text>;

2.3 Адаптация разрешения изображения

Разрешений мобильных телефонов становится все больше и больше, особенно Android, React Native может загружать изображения разных размеров в соответствии с разными разрешениями, просто различайте имена изображений.

  • Предоставление изображений в разных разрешениях

Например, у нас есть картинка под названиемtest.png, размер40 x 40(единичный пиксель), чтобы добиться адаптивного разрешения экрана, нам также необходимо предоставить свое изображение 2x изображения и изображения 3x, так что одно изображение соответствует 3 размерам, следующим образом:

# 一张图片提供 3个尺寸

test.png # 尺寸 40 x 40
test@2x.png # 尺寸 80 x 80
test@3x.png # 尺寸 120 x 120

name@nxЭто соглашение об именовании изображений n (n > 1), и React Native также оценивает размер изображения на основе именования.

  • использовать

Используйте его непосредственно при цитировании изображенийИмя изображения без суффикса, например, напрямую используяtest.png,следующим образом:

/**
 * ScreenTab3/view.js
 */

<Image
  source={require("../../assets/images/test.png")}
  style={{ height: pxToDp(80), width: pxToDp(80) }}
/>

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

  • iphone6: изображение в 2 раза (после увеличения изображения видно, что есть2Xшрифт)
  • iphone7Plus: 3-кратное увеличение изображения (после увеличения изображения видно, что есть3Xшрифт)
  • Nexus4: удвоенный график
  • Pixel2: 3-кратное увеличение

自定加载不同分辨率图片

3. Измените значок на рабочем столе, отображаемое имя приложения и установите стартовую страницу.

Изменить значки на рабочем столе и отображаемые имена приложений относительно просто, а настроить начальную страницу немного сложнее. Кроме того, iOS, изменяющая значок на рабочем столе, отображаемое имя приложения и настройку стартовой страницы, необходимо выполнять в Xcode.

3.1 Установка значков на рабочем столе

Поскольку значок приложения соответствует нескольким размерам, его слишком сложно переписать вручную, этот веб-сайт может быть создан автоматически.MakeAppIcon.

Требуются не все размеры изображений, см. ниже.

  • iOS

Если быть точным, это нельзя назвать установкой значка на рабочем столе, а значком приложения, потому что нам нужно установить не только значок, отображаемый на рабочем столе, но и значок приложения при настройке и значок приложения при отправке сообщений. если вы хотите опубликовать приложение в App Store, вам также необходимо установить значок приложения для отображения в Apple Store.

1) Подготовка изображения

Значки приложений, используемые в разных местах выше, имеют разные размеры, как показано ниже (Только для iphone, не включая ipad, iwatch):

размер имя использовать Это необходимо
120x120 Icon-60@2x.png Значки на рабочем столе (2x) должен
180x180 Icon-60@3x.png Иконки на рабочем столе (3x) Необязательный, но рекомендуемый параметр
80x80 Icon-40@2x.png Иконки прожекторов (2x) Необязательный, но рекомендуемый параметр
120x120 Icon-40@3x.png Иконки прожекторов (3x) Необязательный, но рекомендуемый параметр
58x58 Icon-29@2x.png Значок настроек (2x) Необязательный, но рекомендуемый параметр
87x87 Icon-29@3x.png Значок настроек (3x) Необязательный, но рекомендуемый параметр
40x40 Icon-20@2x.png Значки уведомлений (3x) Необязательный, но рекомендуемый параметр
80x80 Icon-20@3x.png Значки уведомлений (3x) Необязательный, но рекомендуемый параметр
1024x1024 iTunesArtwork@2x.png App Store (2x) должен

Название не означает, что оно должно быть таким же, как указано выше, ноIcon, размер (например60) и увеличение (@nx), типpng.

2) Перетащите изображение в указанное место в Xcode, а именно:Project Navigator -> Images.xcassets -> AppIcon,Как показано ниже

iOS AppIcon

После завершения перетаскивания просмотрите каталог проекта через файловый менеджер, и вы также найдете соответствующие картинки.

  • андроид

Значки приложений для Android относительно просты, вам нужно только установить значки на рабочем столе. установить местоположение вyourApp/android/app/src/main/res/Под каталогом по умолчанию в этом каталоге четыре папки, и каждой из них соответствует изображение значка на рабочем столе одного размера Размер изображения разный, но имя одинаковое.ic_launcher.png, следующим образом:

Имя папки имея в виду Размер изображения внутри папки Имя изображения внутри папки
mipmap-ldpi Low Density Screen 36x36 ic_launcher.png
mipmap-mdpi Medium Density Screen 48x48 ic_launcher.png
mipmap-hdpi High Density Screen 72x72 ic_launcher.png
mipmap-xhdpi Extra-high density screen 96x96 ic_launcher.png
mipmap-xxhdpi xx-high density screen 144x144 ic_launcher.png
mipmap-xxxhdpi xxx-high density screen 192x192 ic_launcher.png

Если вы пользуетесь сервисом MakeAppIcon, поместите все соответствующие папки прямо вres/Каталог в порядке, иначе иконка будет заменена вручную.

Ненужные файлы можно удалять по актуальным потребностям, например, экранов с разрешением 120 DPI очень мало, поэтому эту папку можно удалить.

3.2 Изменить отображаемое имя приложения

  • iOS

Откройте меню настроек проекта (дважды щелкните имя проекта или нажмите и затем выберите Targets --> yourProject справа), введитеinfoварианты, вCustom iOS Target Propertiesдобавлено вBundle display name,Этоvalueэто имя приложения. Конкретные настройки следующие:

ios修改app名称

  • андроид

Android изменяет отображаемое имя приложения в этом файлеyourApp/android/app/src/main/res/values/strings.xml.

strings.xmlЭтот файл очень простой, все содержимое выглядит следующим образом:

<resources>
    <string name="app_name">你的app名称</string>
</resources>

заменять你的app名称Просто имя, которое вы хотите.

ПРИМЕЧАНИЕ:

Для Android также измените имя пакета по умолчанию (applicationId), если не изменено, если система отслеживает применяемые в настоящее времяapplicationIdЕсли оно совпадает с установленным приложением, но имеет другую подпись, будет сообщено об ошибке: «Подпись несовместима. Возможно, приложение было злонамеренно изменено».

Измените имя пакета в этом файле:yourApp/android/app/build.gradle:

// ...

defaultConfig {
    applicationId "com.yourAppId"
    // ...
}

// ...

3.3 Настройка стартовой страницы

Здесь используются сторонние плагиныreact-native-splash-screen, руководство на официальном веб-сайте было очень подробным, вот краткое введение.

  • Установить зависимости в проекте

1) Скачать зависимости

yarn add react-native-splash-screen

2) Добавить в проект

react-native link react-native-splash-screen

3) Настроить в React Native

Это относится к настройке, когда стартовая страница исчезает.Следующий код - стартовая страница исчезает через 5 секунд после загрузки домашней страницы.

/**
 * ScreenHome/index.js
 * 设置启动页消失时间
 */
import SplashScreen from "react-native-splash-screen"; // 引入 react-native-splash-screen

export default class ScreenHome extends Component {
  // ...other code
  componentDidMount() {
    // 隐藏启动页,如果不设置消失时间,在组件加载完启动页自动隐藏
    setTimeout(() => {
      SplashScreen.hide();
    }, 5000);
  }
  // ...other code
}
  • настройки iOS

1) ОбновитьAppDelegate.m:

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "SplashScreen.h"  // 导入启动页插件

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...其他代码
    [self.window makeKeyAndVisible];
    [SplashScreen show];  // 显示启动页
    return YES;
}

@end

2) Подготовьте изображение стартовой страницы

Файл должен быть изображением в формате png, наименование должно соответствовать размеру, см. следующее наименование:

Для автоматической генерации вы можете использовать эту страницу:appicon

размер имя использовать Это необходимо
640 x 960 Default@2x.png iPhone 4 Не требуется, рекомендуемая настройка
640 x 1136 Default-568h@2x.png iPhone 5 Не требуется, рекомендуемая настройка
750 x 1334 Default-667h@2x.png айфон 6, портрет Обязательно (должно быть хотя бы одно изображение заставки)
1242 x 2208 Default-736h@3x.png iPhone 6 Plus, портрет Не требуется, рекомендуемая настройка
2208 x 1242 Default-Landscape-736h@3x.png iPhone 6 Plus, альбомная ориентация Не требуется, рекомендуемая настройка
1125 × 2436 Default-812h@3x.png iPhone X, портрет Не требуется, рекомендуемая настройка
2436 x 1125 Default-Landscape-812h@3x.png iPhone X, пейзаж Не требуется, рекомендуемая настройка

NOTE:

  • Многие учебники дают больше размеров стартовой страницы, чем указано выше, что может быть вызвано разными версиями Xcode.Xcode 9.2, iOS 7+ нужны только семь вышеуказанных размеров;
  • Имя не должно использоваться напрямую в соответствии с вышеуказанными требованиями.Default尺寸x尺寸.pngтакже может;

3) Настройте страницу запуска в Xcode

Сначала создайте новыйLaunchImageФайл следующим образом:

设置启动页

затем вgeneralВ настройках указать стартовую страницу на только что созданнуюLaunchImageдокумент,Обратите внимание, что файл экрана запуска должен быть пустым, иначе он будет указывать на страницу запуска по умолчанию в LaunchScreen.xib.:

设置启动页

  • Конфигурация Android

1) ОбновитьMainActivity.java:

import android.os.Bundle; // here
import com.facebook.react.ReactActivity;
// react-native-splash-screen >= 0.3.1
import org.devio.rn.splashscreen.SplashScreen; // here
// react-native-splash-screen < 0.3.1
import com.cboy.rn.splashscreen.SplashScreen; // here

public class MainActivity extends ReactActivity {
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this);  // here
        super.onCreate(savedInstanceState);
    }
    // ...other code
}

2) Новыйlaunch_screen.xml

существуетapp/src/main/res/layoutсоздан вlaunch_screen.xml(если нетlayoutкаталог, новый), содержание следующее:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/launch_screen">
</LinearLayout>

3) Подготовьте изображения заставок разных размеров и вставьте их в проект

Android ищет начальную страницу по пути к папке, поэтому стартовые страницы разных размеров имеют одинаковое имя и все они называются какlaunch_screen.png, но для размещения в другой папке каталог размещения папкиyourApp/android/app/src/main/res/, имя и соответствующий размер изображения следующие:

Имя папки имея в виду Размер изображения внутри папки Имя изображения внутри папки
drawable-ldpi Low Density Screen 240x320 launch_screen.png
drawable-mdpi Medium Density Screen 320x480 launch_screen.png
drawable-hdpi High Density Screen 480x800 launch_screen.png
drawable-xhdpi Extra-high density screen 720x1280 launch_screen.png
drawable-xxhdpi xx-high density screen 960x1600 launch_screen.png
drawable-xxxhdpi xxx-high density screen 1280x1920 launch_screen.png

Рекомендуется перейти непосредственно из480x800Просто начните с размещения 4 изображений.

4) Оптимизация короткого белого экрана перед появлением стартовой страницы

На данный момент функция стартовой страницы работает нормально, но если вы посмотрите внимательно, то увидите, что перед появлением стартовой страницы появится короткий белый экран.В это время вы можете изменитьandroid/app/src/main/res/values/styles.xmlрешить:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <!--设置透明背景-->
        <item name="android:windowIsTranslucent">true</item>
    </style>
</resources>

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

5)Решить проблему флешбека после завершения установки и настройки Android 6.0, 7.0Ссылка на следующие настройки:

существуетandroid/app/src/main/res/valuesНовое нижеcolors.xmlфайл со следующим содержимым:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- this is referenced by react-native-splash-screen and will throw an error if not defined.  its value does nothing, just here to avoid a runtime error. -->
    <color name="primary_dark">#000000</color>
</resources>

Поскольку для реагирования на собственный экран-заставку требуется файл с именемprimary_darkЗначение цвета используется в качестве цвета строки состояния.

3.4 Окончательная визуализация

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

图标及启动页

Выпуск четырех пакетов

4.1 Выпуск пакета Android

  • Создать подпись
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000

При использовании Mac каталог, в котором выполняется команда, является произвольным. Но обязательно берегите себяmy-release-key.keystoreЕсли вы забудете подписать файл, вы не сможете обновить его в исходном приложении, вы сможете только переупаковать его для выпуска. В то же время неkeystoreФайлы помещаются в систему контроля версий.

  • установить переменные градиента

1) Сначала ставим файл подписиmy-release-key.keystoreположить в каталогyourApp/android/app/Вниз

2) Изменить файлyourApp/android/gradle.propertiesДобавьте следующий код (замените*****для правильного пароля хранилища ключей, псевдонима и пароля ключа):

MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****

3) Добавьте информацию о подписи в конфигурацию градиента приложения.

редактировать файлyourApp/android/app/build.gradleДобавить информацию о подписи

android {
    ...
    defaultConfig { ... }
    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
                storeFile file(MYAPP_RELEASE_STORE_FILE)
                storePassword MYAPP_RELEASE_STORE_PASSWORD
                keyAlias MYAPP_RELEASE_KEY_ALIAS
                keyPassword MYAPP_RELEASE_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}
  • Пакет

Введите следующую команду в терминал

cd android && ./gradlew assembleRelease

Дождитесь завершения сборки, затем вы можетеyourApp/android/app/build/outputs/apk/release/app-release.apkНайдите скомпилированную версию выпуска в формате .

ПРИМЕЧАНИЕ. Если вы столкнулись с этой ошибкой:Execution failed for task ':app:processReleaseResources', внесите следующие изменения:

существуетyourApp/android/gradle.propertiesДобавьте следующий код в конец файла:

classpath 'com.android.tools.build:gradle:3.0.0'
distributionUrl=https://services.gradle.org/distributions/gradle-4.1-all.zip
android.enableAapt2=false

Если у вас есть другие вопросы, пожалуйста, обратитесь к этой статье:Пакет Android освобождает эти ямы

4.2 Выпуск пакета iOS

Упаковывать и выпускать iOS немного хлопотно.Ограничение для большинства не-iOS-разработчиков заключается не в самом React Native, а в собственном механизме Apple.Например, необходимо иметь учетную запись разработчика Apple. О выпуске пакета для iOS планируется написать еще одну статью. Если вы хотите понять процесс публикации, вы можете обратиться к этим двум статьям:IOS App Store Release Подробные графические учебники,Подробные шаги по упаковке React Native iOS

Одно замечание: при упаковке--entry-fileAndroid и iOS — это один и тот же входной файлindex.js, не различая Android/iOS

Пятое резюме

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

Конечно, с производственной точки зрения завершенность этой демонстрации не высока, например, многие стили все еще находятся в самом примитивном состоянии, такие как WebView (H5, встроенный в приложение), выпадающее обновление и т. д. не участвуют. Среди них общие функции, такие как WebView и pull-to-refresh, будут постепенно интегрироваться в эту демонстрацию, но стиль не предназначен для чрезмерной оптимизации, потому что с точки зрения использования, чем выше завершение стиля, тем ухудшает настраиваемость и, таким образом, делает код менее читаемым. Будем надеяться, что эта демонстрация сможет стать полным, универсальным, но не раздутым каркасом.

Однако для одного и того же набора кода стили, отображаемые на Android и iOS, будут разными, поэтому для этого будет написана отдельная статья, объясняющая это отдельно.

использованная литература

Choose transition mode for each screen in StackNavigator
Опыт адаптации разработки React Native
Apple Developer - App Icon
На эмуляторе Android 4.0 работает нормально, а на Android 6.0 и на телефоне 7.0 вылетает, что делать не знаю
Issues with resources generated by react in Android Studio 3
Единицы измерения React Native по умолчанию и адаптивная схема макета