React Native Android and iOS: development of mobile apps

0

React Native For Android and iOSIf you want to develop an app for smartphones, there are many different approaches available. So you have to z. For example, decide whether a mobile web application is sufficient or whether a native app is required for special features. The open-source framework React Native makes it possible to program native apps cross-platform and parallel for Android and iOS in JavaScript. This article shows how to get started with app development with React Native by programming a simple game.

The 2015 React Native framework, introduced by Facebook as an open source project, has many beneficial features. Parallel development of high-performance, native apps on a code base for Android, iOS and other target platforms with many useful tools that ensure high productivity, are particularly noteworthy. Therefore, React Native with more than 60,000 stars is one of the most popular projects on GitHub and many well-known companies such. For example, Airbnb and Tesla use the framework to develop their apps.

A game for memory training

 

React Native Javascript

You will develop a simple game that trains your short-term memory. As shown in Figure, the app consists of three colored squares arranged one below the other. At the bottom is a button to start the game. After the game starts, one of the three squares flashes in random order five times in a row. After that you have to reproduce exactly this order by pressing the appropriate squares to win a game round.

 

Preparation: Develop apps in the browser


In order to develop a mobile app with React Native, nothing needs to be installed on the computer – all it takes is a web browser. Expo Snack is a web service that provides a React Native programming environment directly in the browser. As shown in Figure 1, the source code of the app is edited in an editor area and to the right is a preview of the app either in a virtual Android device or iPhone dar. The preview can be activated by the control button preview in the footer. If you want, you can try the game online right now. It can be used in the browser at Expo Snack.

However, because the preview of the app in the browser takes some space and sometimes only after a certain wait is started, I recommend the use of the App Expo, which you get for free for Android or iOS in the respective AppStore. A search for Expo Client in the AppStore will lead you to this app as well.

Expo Snack generates an unique QR code for an app, which can be displayed in the browser using the QR Code button. In the Expo app on the smartphone, there is a feature that allows this QR code to be scanned so that the app is loaded directly onto the phone and executed there. Expo Snack and the Expo app are examples of the outstanding tools in the React Native environment. In particular, with Expo Snack the entry into the programming with React Native is immediately possible.

Of course, React Native also provides a comprehensive development environment that can be set up on your own computer. But since this takes a lot of time, you will find the notes at the end of the article. Now we will start to program the app!

 

Getting started with Expo Snack


I will now describe the necessary development steps for the example app. If you enter the listed code fragments in the browser in Expo Snack, you will already get a first impression of how to program with React Native.

I have provided the starting point of the program code in Expo Snack for this article. When navigating to Expo Snack in the browser, you will first see a QR code for the app shown. If you have the App Expo installed on your smartphone, then you can scan the QR code there to run the app on your phone. Otherwise, you can close the displayed QR code and open the preview of the app in the browser through the Preview button at the bottom of the web page. In addition, I recommend hiding the Files view and the Component list (Components) with the appropriate buttons in the footer, giving you more space for the editor. If you want to use the preview of the app in the browser, then a certain waiting time might be necessary to start the preview.

If you want to change and cache your code, you can press the Save changes button. Note, however, that you will receive a new URL each time. If you want to reload the app on your smartphone with Expo, you can shake the device briefly to get a menu of useful features. Please also note that if the code is entered in the editor, faults in the app can occur in the meantime since Expo Snack executes the program code immediately after each change. The app then displays a red screen with the error message. Do not let that irritate you, because if the entered source code is finally correct, the app will also be displayed as expected.

 

A simple component


Let’s get to the code of the prepared app for you. The editor area shows the contents of the App.js file. There a simple component is declared. For an app developed with React Native and Expo, App.js is the entry point and its component is displayed when the app is opened.

The following listing contains the code in App.js as it is in the browser of Expo Snack in the browser:

import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';

export default class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.box} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    backgroundColor: 'red',
    width: 150,
    height: 150
  }
});

 

The code consists of three sections, each separated by an empty line:

import statements for required APIs and components,
Definition of a separate component as class (class) and
Declaration of styles for the representation and the layout of the component

When you program an app with React Native, it essentially means implementing your own components and using them with other components. Often, modern language concepts of JavaScript are used, which were introduced with ECMAScript 2015 (ES 2015) and later versions. This shows this z. For example, with the import statements and the class definition with class. Each of its own components is usually declared as a subclass of Component and must implement at least the method render, which in turn returns an expression that describes the UI declaratively. In the case of this component this is the following fragment:

<View style={styles.container}>
  <View style={styles.box} />
</View>

 

This is markup, which is declared in a syntax called JSX. Although JSX is reminiscent of HTML or XML, it is translated into JavaScript before the program code is executed. Here, an outer view element contains another view component. In React Native, View is roughly equivalent to a div in HTML – a block element with no special appearance. The two View elements each have a style attribute that refers to summarized styling properties.


Styling in React Native


In React Native there is an API called StyleSheet which makes the declaration of styles easier. This API is imported at the beginning of the code alongside the other required components and APIs. Styles are also defined in JavaScript, with some similarity to CSS. In principle, styles are objects that consist of properties that in turn contain any styling instructions. For example, the container property summarizes three statements:

container: {
  flex: 1,
  alignItems: 'center',
  justifyContent: 'center',
},

 

With flex: 1, the component will assume a maximum extent. Its content is centered along the vertical main dive and additionally perpendicular to this axis, similar to the flexbox layout from the CSS specification due to justifyContent: ‘center’ (by alignItems: ‘center’). The View component, which is indicated by the styles in styles.box as a red square, therefore appears in the middle of the screen.

By specifying the styles in the file in which the component is also declared, the component is self-describing and allows its reuse, since the complete information for its representation (render and styles) is combined in one place. This is one of the benefits of component-based programming that React Native receives from the underlying React Web library.


Show three squares and a button


In the next step, add two more squares to the app and place a button at the bottom of the screen. The following listing contains the necessary changes:

import React, { Component } from 'react';
import { Button, View, StyleSheet } from 'react-native';

export default class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.box} />
        <View style={styles.box} />
        <View style={styles.box} />
        <Button title="Neues Spiel" onPress={() => alert('Klick!')} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'space-around',
    paddingTop: 30
  },
  box: {
    backgroundColor: 'red',
    width: 150,
    height: 150
  }
});

 

In addition, a button component is contained in the import statements, and render now displays three squares (view elements) below each other followed by a button. A button requires a title attribute for the label (here “new game”) and onPress defines this Behavior when tapping the button: an anonymous arrow function (another important new feature in the ES 2015 version of JavaScript) is an alert panel with alert:

onPress={() => alert('Klick!')}

 

ReactNative screen 2

Fig. 2: Native UI elements such. B. Buttons appear according to the respective platform (Android left, iOS right). © Prof. dr. Erik Behrends

The styling for the outer view element (container) has also been changed. For the squares to appear vertically spaced, justifyContent now has the value ‘space-around’ and with paddingTop: 30, the first square gets a little bit further from the top of the screen.

As shown in Figure 2, a button appears as a native UI element matching the platform. According to the UI guidelines, this is just text on the iPhone, and in Android this is a button consisting of a blue, slightly floating surface labeled with capital letters.

 

Integrate touchable components


Now only two adjustments are needed to make the app look like it should have been in the game: The three squares should appear in blue, red and green and it should be possible to tap them. Make the following changes:

import React, { Component } from 'react';
import { Button, TouchableOpacity, View, StyleSheet } from 'react-native';

export default class App extends Component {
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity>
          <View style={[styles.box, { backgroundColor: 'blue' }]} />
        </TouchableOpacity>
        <TouchableOpacity>
          <View style={[styles.box, { backgroundColor: 'red' }]} />
        </TouchableOpacity>
        <TouchableOpacity>
          <View style={[styles.box, { backgroundColor: 'green' }]} />
        </TouchableOpacity>
        <Button title="Neues Spiel" onPress={() => alert('Klick!')} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'space-around',
    paddingTop: 30,
  },
  box: {
    width: 150,
    height: 150,
  },
});

 

The TouchableOpacity component is imported, and each View element that represents a square is now surrounded by TouchableOpacity. In addition, each square receives the desired color, z. Eg the top square:

<TouchableOpacity>
  <View style={[styles.box, { backgroundColor: 'blue' }]} />
</TouchableOpacity>

 

Note that the affected style attributes now contain an array. This consists of the styles in styles.box for defining the dimensions (width and height) and contains explicitly the desired color (backgroundColor). TouchableOpacity ensures that the squares can now be tapped, which is visible by a brief flash. The user interface is now implemented. It just lacks the code for the actual game.


Simple variant of the game with state (state)


At any point in time, the game or app can be in exactly one of the following states, which can be reached through certain processes:

  1. No game is active (the app was previously launched or just ended a game).
  2. A game is active (the bottom button has been tapped) and a list of colors has been set.
  3. The user taps the wrong square in the order to be reproduced, ending the game.
  4. The user taps on the correct square in the order. The current number of sequences is cached for the next tap of a square.

So there are three properties that can change their state in the game:

  1. game – game is active (true) or not (false),
  2. colorList – a list (array) of colors that the user must select in exactly that order, eg. B. [‘blue’, ‘red’, ‘green’] and
  3. pressed – a number from 0 to colorList.length – 1, which represents the last tapped square.

In React Native, components can manage their state in an object called state. If this object changes, then the render method is automatically executed so that the UI updates. The initial state of a component can be declared with state at the beginning of the class. Complete the class app with a corresponding assignment:

export default class App extends Component {
  state = { game: false, colorList: [], pressed: 0 };
  // der Rest bleibt unverändert…

 

The app starts so that no game is active, no colors have been set and still no square was tapped. If the user now taps the button at the bottom of the screen, then begins a new game. Therefore, adjust the Button component so that a _newGame method is executed when tapping:

<Button title="Neues Spiel" onPress={() => this._newGame()} />

 

It’s a convention in React Native to start the name of your own methods that are not part of the framework with an underscore. Declare this method within the class z. For example, before render as follows:

_newGame() {
  if (this.state.game) return;
  const theColors = ['blue', 'red', 'green'];
  this.setState({ game: true, colorList: theColors, pressed: 0 });
}

 

If in the state object the property this.state.game has the value true, the method ends prematurely with the return statement, because a game is already active. Otherwise, for the first slight variant of the game (even without random colors), the theColors constant gets three colors in the order of the three squares from top to bottom. The following is a call to this.setState, a method that React Native provides to change the state of the component. Here we activate the game (game: true), assign to the color list the (not yet) random fangs (colorList: theColors) and initialize the counter for the last tapped square (pressed: 0).

Now add the following method _checkColor to the App class (for example, below _newGame):

_checkColor(color) {
  const { game, pressed, colorList } = this.state;
  if (!game) return;
  if (colorList[pressed]!== color) {
    alert('Leider hast du verloren!');
    this.setState({ game: false });
  } else if (pressed === colorList.length - 1) {
    alert('Super, du hast gewonnen!');
    this.setState({ game: false });
  } else {
    this.setState({ pressed: pressed + 1 });
  }
}

 

The code in _checkColor reads the current state through construc- tive assignments into constants named like the state properties ({game, pressed, colorList}). If no game is currently active, the method ends with return. In the case of an active game, there are three different situations:

  1. The wrong square was tapped – this leads to a corresponding hint and to the end of the game.
  2. The correct square was tapped and this is the last of the order – a fitting indication appears that the user has won and the game ends.
  3. The correct square was tapped and the current counter is increased by 1 (in this case a game is active and we have not yet reached the end of the order).

Now adjust the method render so that a tap (onPress) of a square calls the method _checkColor with the corresponding color value:

render() {
  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={() => this._checkColor('blue')}>
        <View style={[style
s.box, { backgroundColor: 'blue' }]} />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => this._checkColor('red')}>
        <View style={[styles.box, { backgroundColor: 'red' }]} />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => this._checkColor('green')}>
        <View style={[styles.box, { backgroundColor: 'green' }]} />
      </TouchableOpacity>
      <Button title="Neues Spiel" onPress={() => this._newGame()} />
    </View>
  );
}

 

Now you can test the game, even if the order of the colors is always the same: blue, red and then green.

The gradual changes to the program code contained u. a. Two new methods and therefore the following listing represents the complete component app after the just made adjustments:

import React, { Component } from 'react';
import { Button, TouchableOpacity, View, StyleSheet } from 'react-native';

export default class App extends Component {
  state = { game: false, colorList: [], pressed: 0 };

  _newGame() {
    if (this.state.game) return;
    const theColors = ['blue', 'red', 'green'];
    this.setState({ game: true, colorList: theColors, pressed: 0 });
  }

  _checkColor(color) {
    const { game, pressed, colorList } = this.state;
    if (!game) return;
    if (colorList[pressed]!== color) {
      alert('Leider hast du verloren!');
      this.setState({ game: false });
    } else if (pressed === colorList.length - 1) {
      alert('Super, du hast gewonnen!');
      this.setState({ game: false });
    } else {
      this.setState({ pressed: pressed + 1 });
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={() => this._checkColor('blue')}>
          <View style={[styles.box, { backgroundColor: 'blue' }]} />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => this._checkColor('red')}>
          <View style={[styles.box, { backgroundColor: 'red' }]} />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => this._checkColor('green')}>
          <View style={[styles.box, { backgroundColor: 'green' }]} />
        </TouchableOpacity>
        <Button title="Neues Spiel" onPress={() => this._newGame()} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'space-around',
    paddingTop: 30,
  },
  box: {
    width: 150,
    height: 150,
  },
});

 

Create random colors


Now we will set five random colors at the beginning of a game. This happens in the method _newGame:

_newGame() {
  if (this.state.game) return;
  const theColors = ['blue', 'red', 'green'];
  const colorList = Array.from(
    { length: 5 },
    () => theColors[Math.floor(Math.random() * theColors.length)]
  );
  console.log(colorList);
  this.setState({ game: true, colorList: colorList, pressed: 0 });
}

 

The above code generates an array of five random color names with the possible values from theColors (‘blue’, ‘red’, ‘green’) and assigns them to the constants colorList. With console.log, this generated list is output and then set in the state object with setState.

If you test the game now, then the selected colors appear in the console at the beginning of the game. Expo Snack has a special section (LOGS), in which outputs can be reproduced in the browser with console.log. To open this area, click below the editor on the far left of the footer (next to Prettier).

Show the color order with animations


According to the five colors, the squares are now supposed to flash briefly in exactly this order at the beginning of the game. To do this we will define animations for which React Native will provide the API Animated. Import this API and expand the initial state to state with three additional properties (blue, red, green) as follows:

import React, { Component } from 'react';
import {
  Animated,
  Button,
  TouchableOpacity,
  View,
  StyleSheet
} from 'react-native';

export default class App extends Component {
  state = {
    game: false,
    colorList: [],
    pressed: 0,
    blue: new Animated.Value(1),
    red: new Animated.Value(1),
    green: new Animated.Value(1)
  };

  // der Rest bleibt unverändert

 

To make the squares blink, we will animate the value of the styling property opacity in an interval from 0 to 1 for the affected view element, so that the square becomes invisible (opacity: 0) and then reappears (opacity: 1 ). We prepare this with the properties blue, red and green in the initial state object. With Animated.Value (1) we get a value that can be dynamically animated.

So that we can animate the squares or their styling property opacity with values from Animated.Value, we will now use components of the type Animated.View instead of the view elements. So in the render method, replace the view components of the three squares with Animated.View as shown in this listing:

render() {
  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={() => this._checkColor('blue')}>
        <Animated.View
          style={[
            styles.box,
            { backgroundColor: 'blue', opacity: this.state.blue }
          ]}
        />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => this._checkColor('red')}>
        <Animated.View
          style={[
            styles.box,
            { backgroundColor: 'red', opacity: this.state.red }
          ]}
        />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => this._checkColor('green')}>
        <Animated.View
          style={[
            styles.box,
            { backgroundColor: 'green', opacity: this.state.green }
          ]}
        />
      </TouchableOpacity>
      <Button title="Neues Spiel" onPress={() => this._newGame()} />
    </View>
  );
}

 

The squares can now be animated, because in the style attribute for opacity, they contain the current value of the corresponding property in the state object, which initially has the value Animated.Value (1). We define the animations directly after starting a game in the method _newGame:

_newGame() {
  if (this.state.game) return;
  const theColors = ['blue', 'red', 'green'];
  const colorList = Array.from(
    { length: 5 },
    () => theColors[Math.floor(Math.random() * theColors.length)]
  );
  this.setState({ game: true, colorList: colorList, pressed: 0 });
  let animations = [];
  colorList.forEach(color => {
    animations.push(
      Animated.timing(this.state[color], {
        toValue: 0,
        duration: 500
      })
    );
    animations.push(
      Animated.timing(this.state[color], {
        toValue: 1,
        duration: 500
      })
    );
  });
  Animated.sequence(animations).start();
}

 

We first assign an empty array to a local variable animation. This is filled with two animations for each of the previously randomly chosen colors. The first animation sets the corresponding value for opacity in the state to 0, which runs over a period of 500ms (Animated.timing). This will hide the square with an animation until it is invisible. The second animation will eventually increase the opacity value to 1 over a half-second period, making the square visible again. The animations containing 10 animations (two per square in order) are finally executed by calling Animated.sequence (animations) .start ().

Summary

Congratulations! You have programmed a game as a mobile app online in the browser in just over 100 lines of code. This app works with both Android devices and the iPhone. With components, styling and animations, you’ve already gotten to know some important aspects of React Native.

You will find the complete program code of the game on the one hand online at Expo Snack [4] and on the other hand here for completeness in the following listing:

import React, { Component } from 'react';
import {
  Animated,
  Button,
  TouchableOpacity,
  View,
  StyleSheet
} from 'react-native';

export default class App extends Component {
  state = {
    game: false,
    colorList: [],
    pressed: 0,
    blue: new Animated.Value(1),
    red: new Animated.Value(1),
    green: new Animated.Value(1)
  };

  _checkColor(color) {
    const { game, pressed, colorList } = this.state;
    if (!game) return;
    if (colorList[pressed]!== color) {
      alert('Leider hast du verloren!');
      this.setState({ game: false });
    } else if (pressed === colorList.length - 1) {
      alert('Super, du hast gewonnen!');
      this.setState({ game: false });
    } else {
      this.setState({ pressed: pressed + 1 });
    }
  }

  _newGame() {
    if (this.state.game) return;
    const theColors = ['blue', 'red', 'green'];
    const colorList = Array.from(
      { length: 5 },
      () => theColors[Math.floor(Math.random() * theColors.length)]
    );
    this.setState({ game: true, colorList: colorList, pressed: 0 });
    let animations = [];
    colorList.forEach(color => {
      animations.push(
        Animated.timing(this.state[color], {
          toValue: 0,
          duration: 500
        })
      );
      animations.push(
        Animated.timing(this.state[color], {
          toValue: 1,
          duration: 500
        })
      );
    });
    Animated.sequence(animations).start();
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={() => this._checkColor('blue')}>
          <Animated.View
            style={[
              styles.box,
              { backgroundColor: 'blue', opacity: this.state.blue }
            ]}
          />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => this._checkColor('red')}>
          <Animated.View
            style={[
              styles.box,
              { backgroundColor: 'red', opacity: this.state.red }
            ]}
          />
        </TouchableOpacity>
        <TouchableOpacity onPress={() => this._checkColor('green')}>
          <Animated.View
            style={[
              styles.box,
              { backgroundColor: 'green', opacity: this.state.green }
            ]}
          />
        </TouchableOpacity>
        <Button title="Neues Spiel" onPress={() => this._newGame()} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'space-around',
    paddingTop: 30
  },
  box: {
    width: 150,
    height: 150
  }
});

 

Next Steps

Maybe you feel like making the game a bit more difficult? To do this, increase the number of randomly selected colors in the program code or shorten the duration of the animations. Maybe you would like to extend the app with a button that allows the order of the colors to be replayed?

Furthermore, I can recommend an interactive tutorial on the basic concepts of React Native, which is also available in the browser.

If you want to go deeper into the development with React Native, then you should equip your computer with the development environment. All you need is an installation of Node.js and the create-react-native-app tool, which works with the Expo app. More about this and React Native in general can be found in the official documentation of React Native.    

  1. Prof. Dr. Erik Behrends: 8 Gründe, warum Sie Ihre Apps mit React Native entwickeln sollten
  2. React Native
  3. Who’s using React Native?
  4. Simple Senso Game
  5. Expo development tools
  6. App bei GooglePlay
    App auf iTunes
  7. Ausgangspunkt für das online-Tutorial auf www.informatik-aktuell.de
  8. React Native – Build your first app in the next 5 minutes
  9. React Native – Getting Started

Source: https://www.informatik-aktuell.de/entwicklung/programmiersprachen/react-native-einstieg-in-die-entwicklung-mobiler-apps.html

 

Share This:

Leave A Reply

Powered by FrontNet