Codementor Events

Building React Native Apps: Retrofitting an iOS app to Android

Published Nov 21, 2016Last updated Jan 18, 2017
Building React Native Apps: Retrofitting an iOS app to Android

I. Introduction to React native

React Native is a framework for building mobile apps using React and JavaScript. It has support for building mobile apps for the iOS and Android platforms. The framework is open-sourced by Facebook on March 2015 and is built on the premise: Learn once, Write anywhere.

Using React for the UI, we can build both web and mobile apps—with React Native used for the latter because it has a set of React components for iOS and Android platforms. The React components available with React Native gets translated to native components which provide a better user experience that are consistent with the mobile platform.

React Native

This Facebook post explains why "native is necessary".

II. Build an app

This tutorial will extend a React Native Todo app from iOS to the Android platform. The Todo app is super-simple. It has two tabs and the first tab has the Todo list.

React Native

When the Todo item is done, press the Done button. This will remove the Todo item from the list. The second tab has the Add Todo form.

React Native

The source code for the iOS app can be found in this Github project. And in this tutorial, we will retrofit the app for the Android platform.

A. Getting started with Android in React Native

There is a Getting started guide for setting up React Native for Android app development. The precise steps vary based on the development OS —Mac, Linux, or Windows. At high level, setting up React Native for Android involves:

  1. Installing Node.
  2. Installing Android Studio.
  3. Setting the ANDROID_HOME path.
  4. Creating a new AVD (Android virtual device or emulator)

Any new React Native project has an Android project.

React Native

The android folder has the app folder which has the source code for the app and the gradle folder which has the associated build settings.

The entry point for the React Native app is index.android.js. When running the React Native app, the Todo component within index.android.js is rendered.

React Native

B. Using equivalent Android components

The iOS app used TabBarIOS component for displaying tabs. For Android, the TabBarIOS component needs to be replaced with ToolbarAndroid component. The render method of the index.android component is shown below.

render() {
    return (
        <View style={styles.container}>
            <ToolbarAndroid
                actions={actions}
                onActionSelected={this.handleActionSelected}
                style={styles.toolbar}
                subtitle={this.state.actionText}
            />
            <ViewPagerAndroid
                ref={c => { this.pager = c; }}
                style={styles.viewPager}
                initialPage={0}
            >
                <View>
                    <List
                        todos={this.state.todos}
                        onDeleteTodo={this.handleDeleteTodo}
                    />
                </View>
                <View>
                    <Add onAddTodo={this.handleAddTodo} />
                </View>
            </ViewPagerAndroid>
        </View>
    );
}

The two views — Add and List — are embedded in the ViewPagerAndroid component. The List component lists all the Todo items. The Add component adds a new Todo item. ToolbarAndroid has the onActionSelected event which must be handled to switch to a new view.

handleActionSelected(position) {
    this.setState({
        actionText: actions[position].title,
    });
    this.pager.setPage(position);
}

The reason we moved TabBarIOS to ToolbarAndroid is because of the native experience we get. The following video highlights the native experience when we select the toolbar actions.

React Native

React Native components render as native components in each platform. Components suffixed with IOS are available only for iOS platform. Components suffixed with Android are available only the for Android platform. For displaying progress, ProgressViewIOS and ProgressBarAndroid are equivalent React Native components for each platform.

C. Android-only components

ToastAndroid is an API available only for Android. It displays a toast or message that appears for a short duration. The handleAddTodo method adds a Todo item to the Todo list. After the item is added, a toast message is displayed, like so:

handleAddTodo(todo) {
    let { todos } = this.state;
    todos = todos.slice();
    todos.push(todo);
    this.setState({ todos });
    ToastAndroid.showWithGravity('Todo is added',
    ToastAndroid.LONG, ToastAndroid.TOP);
} 

React Native

We have already seen the ToolbarAndroid and ViewPagerAndroid components which exist only for the Android platform. DrawerLayoutAndroid is another Android-only React component that wraps the DrawerLayout. DrawerLayout renders the navigation view which can be pulled from the side of the app.

D. Other differences

Platform differences can be explicitly handled with React components. For example, for the TextInput component, we don't want to show a border for the Android platform.

import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
    input: {
        borderColor: '#ccc',
        borderWidth: (Platform.OS === 'ios') ? 1 : 0,
        borderRadius: 5,
    },
});

React Native components are configured using props and some props are available only for the Android platform. For example, the numberOfLines and returnLabel props in TextInput are available only for the Android platform. The keyboardType prop in TextInput also deserves to be mentioned. And not all the keyboard types are available on both platforms. Only default, numeric, email-address and phone-pad are available cross-platform.

III. Wrapping up

While extending an iOS-only React Native app to the Android platform, the following points should be kept in mind:

  1. There are platform specific components. Whenever an iOS-only component is used, an equivalent Android-only component should be used.
  2. There are Android-only components which should be used to enhance the native experience.
  3. Most of the React Native components are cross-platform but there are minor differences in the props available to each platform.

The underlying idea behind React Native is to provide the native experience to the user. There may be occasions where developers prefer to use JavaScript components to have the same look-and-feel across iOS and Android. A better approach is to take advantage of platform-specific features to provide a better native experience. Native experience is preferred over consistent look-and-feel.

There is an accompanying GitHub project to this tutorial that'll help you learn more about React Native. And for further consideration, you can also read this React Native and Ionic comparison tutorial.

Discover and read more posts from Vijay Thirugnanam
get started
post commentsBe the first to share your opinion
dbnex B
7 years ago

I tried to convert this example https://www.raywenderlich.com/165140/react-native-tutorial-building-ios-android-apps-javascript to Android following your document. I just replaced NavigatorIOS to NavigatorAndroid in index.Android.js but I could not get it to work. I am getting this error https://stackoverflow.com/questions/46028469/react-native-element-type-is-invalid-when-converting-ios-to-android , would you mind clarifying. Much appreciated.

dbnex B
7 years ago

… btw, did you have to do any change in package.json and jsonconfig.json or any other files other than index.android.js and index.ios.js?
I am trying to learn RN and how it shares code btw Android and IOS.
Much apprecaited

Vijay Thirugnanam
7 years ago

There is no change in package.json. There is an accompanying Github project. Please feel free to clone it and see if it helps.

dbnex B
7 years ago

yes, I got that. thanks

dbnex B
7 years ago

By far best article so far Vijay, thank you so much.

Vijay Thirugnanam
7 years ago

Thanks for your feedback.

Show more replies