After the development of React Native APP in Part 1 — from the transformation of the official Demo (Part 1), the basic construction of the APP framework is completed. This part mainly discusses UI/ interaction, preparation before the release of the APP and how to release it. The specific content includes:

  • IOS implements modal entry animation of a single page under the premise of using React Navigation
  • Size adaptation
  • Set the startup page, change the desktop icon, APP display name, and appID
  • Packaging releases

The full demo is here in react-native complete-demo

An extension react Navigation

By default, react Navigation only supports global configuration, either card or modal. After configuration, all pages enter animation in the same way.

Two changes are needed to achieve this effect: the StackNavigator API (used in Route.js) and the way it is called when entering a page.

1.1 to modifyStackNavigator API

If the default page status is card after modification, you only need to enter the corresponding page, for example.. Navigate (‘ ScreenSome1 ‘); If you want to use modal to enter a page, you need to use modal in the path, such as:.. Navigate (‘ ScreenSome2Modal ‘).

Notice that if you enter the page in modal mode, you need to customize the header, because the default header style doesn’t work, they’re all stacked together.

/** * route.js * custom StackNavigator, you can select screen entry */
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 }, {// If the page is entered in modal mode, you need to customize the header (the default header style is invalid, they are all stacked together)
      mode: "modal".headerMode: "none"});return ModalStackNavigator;
};

// Set the route
const AppNavigator = StackModalNavigator();
Copy the code

1.2 page call

First, we create a new page ScreenSome2, then let it enter in modal form (enter from below the screen), as a comparison, ScreenSome1 enters in card form (enter from the right side of the screen by default).

Because a page entered in modal form requires a custom header, which is generally just a close button, take ScreenSome2 for example:

/** * ScreenSome2/view.js * custom header (close button) */ < view > {/* TouchableHighlight is the hot area of close button */} <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)}}> Close </Text> </TouchableHighlight> <Text style={{fontSize: PxToDp (36)}}>some2 in modal form </Text> </View>Copy the code

Here is the code from the ScreenHome page:

/** * ScreenHome/view.js * Custom header (close button) */

{
  /* ScreenSome2 enter */ from the right side of the screen
}
<Button
  title="goSome1"
  onPress={() => self.navigation.navigate("ScreenSome1")} / >; {/* ScreenSome2 enter */ from the bottom of the screen
}
<Button
  title="goSome2Modal"
  onPress={() => self.navigation.navigate("ScreenSome2Modal")} / >;Copy the code

Final effect:

Two adaptive

Adaptive mainly includes two aspects: size ADAPTS to screen size, including fontSize, Width, etc.; The picture resolution ADAPTS to the screen resolution, which is often referred to as double graph, triple graph, etc.

2.1 Size adaptation

The principle of size self-adaptation is to adjust the size of the mobile phone screen in proportion by obtaining the width of the screen. For this purpose, a tool function is packaged in config/ pxtodp.js.

The modified directory is as follows:

  • config/pxToDp.jsUtility functions for size conversion

The utility functions for resizing the React Native APP developed in Part 1 — starting with the revamp of the official Demo (part 1) have been added

1) Write adaptive sizing tool functions

Since all data related to size will be converted (fontSize, width, etc.), the converted data will be processed to ensure that: 1. Numbers greater than or equal to 1 round up; 2. If the number is less than 1, set it to 0.5 for ios. For Android, set this to 1 (since android has a wide range of resolutions, a 0.5 on a low-resolution screen will look jagged). The complete code of the tool function is as follows:

/** * pxtodp.js * adaptive layout * @param uiElementPx: the original size given by the UI */

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

// App only has portrait mode, so you can get width only once
const deviceWidthDp = Dimensions.get("window").width;

// The UI defaults to 750
const uiWidthPx = 750;

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

  if (transferNumb >= 1) {
    // Avoid repeating decimals
    return Math.ceil(transferNumb);
  } else if (Platform.OS === "android") {
    // For Android, the minimum value is 1 to avoid jagged borders
    return 1;
  }
  return 0.5;
}

export default pxToDp;
Copy the code

In fact, the screen width obtained by using the dimension.get (‘window’).width may be different from what I expected. For example, iphone7 screen 4.7 “gets 375 width and huawei P9 screen 5.2′ gets 360 width! A bit of a pitfall, this tool function needs to be optimized.

2) Use adaptive sizing tool functions

Use ScreenHome as an example. Use ScreenHome as an example. Use ScreenHome as an example.

/** * ScreenHome/view.js */ / /.. /config/pxToDp"; < font style={{fontSize: pxToDp(36)}}>home</ font >;Copy the code

2.3 Image resolution adaptive

React Native can load images of different sizes based on different resolutions, just by naming them.

  • Provide pictures in different resolutions

For example, we have an image called test.png with a size of 40 x 40 (unit pixel). To achieve adaptive screen resolution, we also need to provide its 2x and 3x images, so that one image corresponds to three sizes, as follows:

# 3 sizes per picture

test.png Size 40 x 40
test@2x.png Size 80 x 80
test@3x.png Size 120 x 120
Copy the code

name@nx is the naming convention for n (n > 1) plogram. React Native also determines the image size based on the naming.

  • use

When quoting an image, use a non-doubling suffix, such as test.png, as follows:

/** * ScreenTab3/view.js */

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

The final effect is as follows:

  • Iphone6:2x image (enlarged image can be seen inside2XThe words)
  • Iphone7Plus: 3x image3XThe words)
  • Nexus4:2x graph
  • Pixel2:3x

Modify the desktop icon, App display name, and set the startup page

It is relatively easy to modify the desktop icon and App display name, and slightly troublesome to set the startup page. In addition, iOS changes the desktop icon, App display name and setting the launch page need to be carried out in Xcode.

3.1 Setting the Desktop Icon

Because App ICONS correspond to multiple sizes, manual rewriting is too cumbersome, the site can automatically generate MakeAppIcon.

Not all sizes are required, see below.

  • iOS

It’s not a desktop icon, it’s an App icon, because you need to set not just the desktop icon, but the App icon when you set it, the App icon when you push it, and if you want to publish to the App Store, You also need to set up the App icon for the Apple Store display.

1) Picture preparation

The sizes of app ICONS used in the above places are different, as follows (only for iPhone, excluding iPad and iWatch) :

size The name of the use Whether must
120×120 [email protected] Desktop Icon (2X) Must be
180×180 [email protected] Desktop Icon (3x) Optional, but recommended
80×80 [email protected] Spotlight icon (2 x) Optional, but recommended
120×120 [email protected] Spotlight icon (3 x) Optional, but recommended
58×58 [email protected] Set icon (2X) Optional, but recommended
87×87 [email protected] Set icon (3x) Optional, but recommended
40×40 [email protected] Notification icon (3x) Optional, but recommended
80×80 [email protected] Notification icon (3x) Optional, but recommended
1024×1024 [email protected] App Store (2x) Must be

The name is not necessarily the same as above, but Icon, size (e.g. 60) and multiplier (@nx) should be PNG.

2) Drag and drop the image to the location specified by Xcode: Project Navigator -> images.xcassets -> AppIcon, as shown below

After the drag and drop is complete, view the project directory through the file manager and you will find the corresponding image.

  • The android

Android app ICONS are relatively simple, just need to set the desktop icon. Set the location in yourApp/android/app/SRC/main/res/directory, this directory is the default has four folders, each corresponding placed inside a desktop icon image size, image size is different, but the same name, unified for ic_launcher. PNG, specific as follows:

Folder name meaning Folder internal picture size Name of the image inside the folder
mipmap-ldpi Low Density Screen 36×36 ic_launcher.png
mipmap-mdpi Medium Density Screen 48×48 ic_launcher.png
mipmap-hdpi High Density Screen 72×72 ic_launcher.png
mipmap-xhdpi Extra-high density screen 96×96 ic_launcher.png
mipmap-xxhdpi xx-high density screen 144×144 ic_launcher.png
mipmap-xxxhdpi xxx-high density screen 192×192 ic_launcher.png

If you are using MakeAppIcon, simply place all folders in the res/ directory, otherwise manually replace the ICONS.

Unnecessary files can be deleted according to actual needs. For example, if the 120 DPI screen is too small, then this folder can be discarded

3.2 Changing the App Display name

  • iOS

Go to the project Settings menu (double click the project name or click and then select Targets –> yourProject on the right), go to the Info option and add the Bundle display name to the Custom iOS Target Properties. The value is the name of the App. The specific Settings are shown below:

  • The android

Android modification App display name in the file yourApp/android/App/SRC/main/res/values/strings. The XML.

The strings. XML file is very simple, and all it contains is this:

<resources>
    <string name="app_name">Your app name</string>
</resources>
Copy the code

Just change the name of your app to whatever you want.

NOTE:

For Android, you need to change the default package name (applicationId). If you do not change the package name, if the system detects that the applicationId of the current application is the same as that of an installed application but the signature is different, the application may have been tampered with.

In this file to modify the package name: yourApp/android/app/build gradle:

// ...

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

// ...
Copy the code

3.3 Setting the startup page

The react-native splash screen plugin is used here. The tutorial on the official website is very detailed. Here is a brief introduction.

  • Install dependencies in the project

1) Download dependencies

yarn add react-native-splash-screen
Copy the code

2) Add to the project

react-native link react-native-splash-screen
Copy the code

3) Configure in React Native

Here refers to the setting of when the start page disappeared, the following code is the home page after loading 5s after the start page disappeared.

/** * ScreenHome/index.js */ ScreenHome/index.js */
import SplashScreen from "react-native-splash-screen"; / / introduction of the react - native - splash screen

export default class ScreenHome extends Component {
  / /... other code
  componentDidMount() {
    // Hide the startup page. If the disappearance time is not set, the startup page is automatically hidden after the component is loaded
    setTimeout((a)= > {
      SplashScreen.hide();
    }, 5000);
  }
  / /... other code
}
Copy the code
  • IOS Settings

1) Update appdelegate.m:

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "SplashScreen.h"  // Import the startup page plug-in@implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary  *)launchOptions {/ /... Other code
    [self.window makeKeyAndVisible];
    [SplashScreen show];  // Displays the startup page
    return YES;
}

@end
Copy the code

2) Prepare the launch page image

The file must be in PNG format and must be named according to the corresponding size. Please refer to the following name:

For automatic generation use this page: Appicon

size The name of the use Whether must
640 x 960 [email protected] iPhone 4 This parameter is optional
640 x 1136 [email protected] iPhone 5 This parameter is optional
750 x 1334 [email protected] The iPhone 6, vertical screen Must (must have at least one launch page image)
1242 x 2208 [email protected] IPhone 6 Plus, portrait screen This parameter is optional
2208 x 1242 [email protected] IPhone 6 Plus, landscape This parameter is optional
1125 × 2436 [email protected] The iPhone X, vertical screen This parameter is optional
2436 x 1125 [email protected] The iPhone X, landscape This parameter is optional

NOTE:

  • Many tutorials give a larger size for the launch page than the one above, which may be due to the different versions of Xcode. Xcode 9.2 and iOS 7+ only require the above seven sizes.
  • The name does not have to be used directly as requested aboveDefault Dimensions x dimensions.pngCan also;

3) Set up the startup page in Xcode

Create a LaunchImage file as follows:

Then in the General setting, point the Launch page to the newly created LaunchImage File. Note that the LaunchScreen File must be empty or it will point to the default Launch page in launchscreen.xib:

  • Android configuration

1) Update mainactivity.java

import android.os.Bundle; // here
import com.facebook.react.ReactActivity;
/ / the react - native - splash screen - > = 0.3.1
import org.devio.rn.splashscreen.SplashScreen; // here
/ / the 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
}
Copy the code

2) Create launch_screen.xml

Create launch_screen.xml in app/ SRC /main/res/layout (if you don’t have a layout directory, create a new one) with the following contents:

<?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>
Copy the code

3) Prepare launch page images of different sizes and put them into the project

Android is through the folder path for the launch page, so, more than the size of the same name as the start page, for the launch_screen. PNG, but should be put in different folders, folder placed directory for yourApp/android/app/SRC/main/res /, The name and the size of the picture to be placed are as follows:

Folder name meaning Folder internal picture size Name of the image inside the folder
drawable-ldpi Low Density Screen 240×320 launch_screen.png
drawable-mdpi Medium Density Screen 320×480 launch_screen.png
drawable-hdpi High Density Screen 480×800 launch_screen.png
drawable-xhdpi Extra-high density screen 720×1280 launch_screen.png
drawable-xxhdpi xx-high density screen 960×1600 launch_screen.png
drawable-xxxhdpi xxx-high density screen 1280×1920 launch_screen.png

It is recommended to place 4 images directly from 480×800.

4) Optimize the short blank screen before the start page appears

Here, the start page functionality is ok, but if you look, you can see start page before there will be a short white, at this point can be modified by android/app/SRC/main/res/values/styles. XML solution:

<resources>
    <! -- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <! -- Customize your theme here. -->
        <! -- Set transparent background -->
        <item name="android:windowIsTranslucent">true</item>
    </style>
</resources>
Copy the code

In fact, this solution does not fundamentally solve the problem: you will find that the application cannot pop up immediately after clicking the image, and there is a short waiting time for filling the pit.

5) To solve the problem of android 6.0, 7.0 after the installation and configuration is complete, refer to the following Settings:

In android/app/SRC/main/res/values below new colors. The XML file, the content is as follows:

<?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>
Copy the code

Because react-native splash-screen requires a color value named primary_dark for the color of the status bar.

3.4 Final effect drawing

After setting the desktop icon, modifying the APP display name and setting the start page, the effect picture is as follows:

Four pack release

4.1 Android package release

  • To generate the signature
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
Copy the code

If you use a MAC, run the command in any directory. However, you must keep your my-release-key.keystore file well. If you forget to sign it, you cannot upgrade it on the original App and can only repackage it for release. Also, do not put the keystore file into version control.

  • Set the gradle variable

1) First put the signature file my-release-key.keystore under yourApp/android/app/

2) modify the file yourApp/android/gradle. The properties to add the following code (replace * * * * *, aliases, and the key for the correct keystore password password) :

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

3) Add signature information to gradle configuration of app

Edit the file yourApp/android/app/build. Gradle add signature information

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
        }
    }
}
Copy the code
  • packaging

Enter the following command on the terminal

cd android && ./gradlew assembleRelease
Copy the code

Waiting for building is completed, can be in yourApp/android/app/build/outputs/apk/release/app – the apk found in the compiled releases.

NOTE: if you encounter this error: Execution failed for task ‘: app: processReleaseResources’, make the following changes:

In yourApp/android/gradle. The properties file finally add the following code:

classpath 'com. Android. Tools. Build: gradle: 3.0.0'
distributionUrl=https:/ / services.gradle.org/distributions/gradle-4.1-all.zip
android.enableAapt2=false
Copy the code

If you have any further questions, check out this article: Android Package Launch Pits

4.2 iOS packaged and released

The iOS package is a bit of a hassle, and the restrictions for most non-ios developers aren’t React Native per se, but Apple’s own mechanics, such as the requirement to have an Apple developer account. IOS package release plan to write another article. For more information on how to launch, check out these two articles: How to launch the iOS App Store and React Native iOS

Note: when packing –entry-file Android and iOS are the same entry file index.js, there is no distinction between Android and iOS

Five summary

So far, a relatively complete React Native App has been completed since the transformation of the official demo. On this basis, it can be continuously expanded and improved.

Of course, from the perspective of production, this demo is not very complete. For example, many styles are still in the original state, such as WebView (embedded H5 in App), drop-down refresh and so on are not involved. Common features such as WebView and pull-down refresh will be gradually integrated into the demo, but styles are not intended to be optimized too much, because more complete styles mean less customizability from a usage perspective, and that also leads to less readable code. Hopefully, this demo will be a complete, universal, but not bloated scaffolding.

However, the same set of code will show different styles on Android and iOS, which will be explained in a separate article.

The resources

Choose Transition mode for each screen in StackNavigator React Native Development adaptation Apple Developer-app Icon in emulator Android 4.0 It’s working fine, Generated by React in Android Studio 3 React Native default unit and adaptive layout solution