petitviolet blog

    React Native for Androidでアプリを作る

    2015-09-16

    QiitaAndroidreactnative

    React Native for Android: How we built the first cross-platform React Native app | Engineering Blog | Facebook Code React Native | A framework for building native apps using React

    Setup

    Android SDK の追加

    Android SDK Manager で以下を install

    • Intel x86 Atom System Image (for Android 5.1.1 - API 22)
    • Intel x86 Emulator Accelerator (HAXM installer)

    react-native の準備

    いくつか install する

    npm install -g react-native-cli
    brew install watchman
    brew install flow
    

    新しい Project を始める

    react-nativeコマンドを使って project を作る

    react-native init ReactSampleProject
    

    これを実行するにはreact-nativerun-androidコマンドを使用する

    cd ./ReactSampleProject
    npm i
    react-native run-android
    

    ここで Build Tools の 23.0.1 が入っていないとエラーが出て終了する

    $ react-native run-android
    Starting JS server...
    Building and installing the app on the device (cd android && ./gradlew installDebug)...
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    A problem occurred configuring project ':app'.
    > failed to find Build Tools revision 23.0.1
    

    ちゃんと入れてから再度走らせると、gradle のタスクが走っている様子が流れる watchmanflowを Homebrew で install していないと React Packager の window ではエラーが出て、アプリは赤いエラー画面だけ表示される

    20150915_092431.png

    ちなみに一度run-androidで成功すると

    $ react-native run-android
    JS server already running.
    Building and installing the app on the device (cd android && ./gradlew installDebug)...
    ...
    

    となり、普通の Android プロジェクトとしてビルド出来るようになります

    20150915_094130.png

    実装

    手元の index.android.js を編集する 例えば以下のように書き換える 参考:Tutorial – React Native | A framework for building native apps using React

    index.android.js
    "use strict"
    
    var React = require("react-native")
    var { AppRegistry, StyleSheet, Text, View, Image, TextInput } = React
    
    var ReactSampleProject = React.createClass({
      getInitialState: function() {
        return { text: "sample" }
      },
      render: function() {
        var MOCKED_MOVIES_DATA = [
          {
            title: "Title",
            year: "2015",
            posters: { thumbnail: "http://i.imgur.com/UePbdph.jpg" },
          },
        ]
        var movie = MOCKED_MOVIES_DATA[0]
        return (
          <View style={styles.container}>
            <Text>{this.state.text}</Text>
            <Text>{movie.title}</Text>
            <Text>{movie.year}</Text>
            <Image
              style={styles.thumbnail}
              source={{ uri: movie.posters.thumbnail }}
            />
            <TextInput
              onChangeText={text => this.setState({ text })}
              value={this.state.text}
            />
          </View>
        )
      },
    })
    
    var styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#F5FCFF",
      },
      thumbnail: { width: 30, height: 30 },
    })
    
    AppRegistry.registerComponent("ReactSampleProject", () => ReactSampleProject)
    

    実機での起動

    Genymotion や AVD なら何も設定しなくても動作しますが、実機の場合は動きませんでした Genymotion 等は F2 押すと menu が開いて[Reload JS]出来ますが、実機の場合は menu ボタンの代わりに 端末を振ると menu が表示されます 表示した menu で[Dev Settings}から[Debug server host for device]を選択し、react-nativeを動かした PC の ip アドレスを指定すると JS が読み込めて起動します

    Screenshot_2015-09-16-09-26-44.png

    コンポーネントを作る

    タップすると入力されたテキストが Toast に表示されるボタンを作ってみる

    toastbutton.js
    var React = require("react-native")
    var { TouchableNativeFeedback, StyleSheet, ToastAndroid, View, Text } = React
    
    var ToastButton = React.createClass({
      propTypes: {
        text: React.PropTypes.string.isRequired,
      },
      render: function() {
        return (
          <TouchableNativeFeedback
            onPress={() =>
              ToastAndroid.show(
                `Your input is ${this.props.text}`,
                ToastAndroid.SHORT
              )
            }
            background={TouchableNativeFeedback.SelectableBackground()}
            style={styles.toastButton}
          >
            <View>
              <Text>Tap me</Text>
            </View>
          </TouchableNativeFeedback>
        )
      },
    })
    
    module.exports = ToastButton
    

    そして

    index.android.js
    <ToastButton text={this.state.text} />
    

    を適当なところに差し込めば良い 表示された"Tap me"をタップするとこうなる Screenshot_2015-09-16-09-33-17.png

    Android のカスタムビューにあたるものがコンポーネントという形で簡単に作れる

    所感

    まだ足りないものが多くて厳しいという印象 画面遷移どうやるんだろう、って思ったけど React だから SPA っぽく書き換えていけば良いから Intent は無いのかな デザインを変更するには CSS っぽいけどちょっと違う独自の style を使っていく必要があるが、ドキュメントも少なくて大変 いわゆるカスタムビューを作るのが簡単なので、慣れれば xml と java で書くよりも速くささっと画面作れそう

    Facebook のオープンソース「React Native for Android」でクロスプラットフォーム開発が簡単になる | TechCrunch Japan この記事によると 3 ヶ月で Android アプリ作ったとあるので、React 理解してるエンジニアがちゃんと使えばそれなりになるのかも知れないが、Titanium みたいなものかと認識している

    from: https://qiita.com/petitviolet/items/a455fe11b48237f7563b