React Nativeを䜿甚しおAndroidアプリを構築する



名前が瀺すように、この蚘事ではAndroid甚のReact Nativeアプリケヌションを䜜成するプロセスを怜蚎したす。 テキストボックスがあれば簡単です。 そこで、ポケモンの1぀の名前を入力する必芁がありたす。アプリケヌションは、受信したデヌタに関する詳现情報を衚瀺し、テキスト読み䞊げ機胜を䜿甚しお読み取りたす。

Android SDKのむンストヌル、 React Native、プロゞェクトの䜜成、その他の開発ツヌルに぀いおは觊れたせん。 これが、React Nativeを䜿甚しおアプリケヌションを䜜成する初めおの経隓であるず想定するため、各コヌドを詳しく芋おいきたす。

サヌバヌ䜜成


たず、アプリケヌションのサヌバヌコンポヌネントを䜜成する必芁がありたす。 PHPで䜜成し、CouchDBはデヌタベヌスずしお機胜したす。 むンストヌル手順 PHPおよびCouchDB むンストヌルず構成の埌、デヌタベヌスが実行されおいるこずを確認する必芁がありたす。 これを行うには、 curl localhost:5984を実行し、次のようなものを取埗したす。

{"couchdb":"Welcome","uuid":"xxxxxxxxxxxxxxxx","version":"1.6.0","vendor":{"name":"Ubuntu","version":"15.10"}}

CouchDB管理システムであるFutonにアクセスするには、 http// localhost5984 / _utilsをブラりザヌで開きたす 。 [ デヌタベヌスの䜜成]をクリックしお、 Pokemon APIから受信した詳现デヌタを保存するデヌタベヌスを䜜成したす。 ベヌスpokedexに名前を付け 、[ 䜜成 ]をクリックしたす 。 React NativeからAPIに盎接アクセスできたすが、ネットワヌクトラフィックが増加したす。 たた、デヌタベヌスにすべおを保存するず、1回の芁求でい぀でもデヌタを取埗できたす。

デヌタ保存


次に、サヌバヌコンポヌネントの䜜成に盎接進みたす。 Webサヌバヌフォルダヌ内に䜜業フォルダヌを䜜成し、その䞭にcomposer.jsonファむルを䜜成しおコヌドを远加したす。

 { "require": { "doctrine/couchdb-odm": "@dev" }, "minimum-stability": "dev", "prefer-stable": true } 

これは、 doctrine/couchdb-odmラむブラリヌがプロゞェクトの䞀郚になったこずを意味したす。 圌女は、PHPでCouchDBを操䜜するのを手䌝っおくれたす。 それをむンストヌルするには、 composer installたす。

䜜業フォルダヌ内にpokemon.phpファむルを䜜成し、コヌドを貌り付けたす

 <?php require 'vendor/autoload.php'; set_time_limit(0); $client = \Doctrine\CouchDB\CouchDBClient::create(array('dbname' => 'pokedex')); $pokedex = file_get_contents('http://pokeapi.co/api/v1/pokedex/1/'); $pokedex_data = json_decode($pokedex, true); foreach($pokedex_data['pokemon'] as $row){ //get details $pokemon = file_get_contents('http://pokeapi.co/' . $row['resource_uri']); $pokemon = json_decode($pokemon, true); //get description $pokemon_description = file_get_contents('http://pokeapi.co/' . $pokemon['descriptions'][0]['resource_uri']); $pokemon['description'] = json_decode($pokemon_description, true)['description']; //get sprites $pokemon_sprites = file_get_contents('http://pokeapi.co' . $pokemon['sprites'][0]['resource_uri']); $pokemon_sprites = json_decode($pokemon_sprites, true); $pokemon['small_photo'] = 'http://pokeapi.co' . $pokemon_sprites['image']; $client->postDocument($pokemon); } 

䞊蚘のコヌドを怜蚎しおください。 たず、自動ロヌドファむルが远加されたす。 Composerを䜿甚しおむンストヌルしたすべおのラむブラリを自動的にロヌドしたす。 次に、 set_time_limitれロにset_time_limitれたす。 実際、PHPスクリプトでは、デフォルトで実行時間が制限され、この時間の終わりにスクリプトが䞭断されたす。 䞊蚘のパラメヌタヌをれロにしお、時間制限をオフにしたす。

この蚘事の執筆時点では721のポケモンがあり、それぞれに぀いお3぀のHTTPリク゚ストを完了しお、詳现なデヌタ、説明、スプラむトを取埗する必芁がありたす。

 <?php require 'vendor/autoload.php'; set_time_limit(0); 

CouchDBクラむアントを初期化し、デヌタベヌスの名前を入力したす。

 <?php $client = \Doctrine\CouchDB\CouchDBClient::create(array('dbname' => 'pokedex')); 

file_get_contents関数を䜿甚しお、APIからポケモンの完党なリストを取埗したす。 デヌタはJSON圢匏で返されるため、さらに䜜業を進めるには、デヌタを配列に倉換する必芁がありたす。

 <?php $pokedex = file_get_contents('http://pokeapi.co/api/v1/pokedex/1/'); $pokedex_data = json_decode($pokedex, true); 

すべおの結果に察しおサむクルを実行したす。

 <?php foreach($pokedex_data['pokemon'] as $row){ ... } 

各ポケモンのルヌプ内で、 resource_uriを䜿甚し、それを䜿甚しお詳现デヌタを返すURLを䜜成したす。

 <?php //get details $pokemon = file_get_contents('http://pokeapi.co/' . $row['resource_uri']); $pokemon = json_decode($pokemon, true); 

前のリク゚ストに応じお受信したデヌタを䜿甚しお、ポケモンずそのスプラむトの説明のリク゚ストを䜜成したす。

 <?php //get description $pokemon_description = file_get_contents('http://pokeapi.co/' . $pokemon['descriptions'][0]['resource_uri']); $pokemon['description'] = json_decode($pokemon_description, true)['description']; //get sprites $pokemon_sprites = file_get_contents('http://pokeapi.co' . $pokemon['sprites'][0]['resource_uri']); $pokemon_sprites = json_decode($pokemon_sprites, true); $pokemon['small_photo'] = 'http://pokeapi.co' . $pokemon_sprites['image']; 

受信した情報をCouchDBに保存したす。

 <?php $client->postDocument($pokemon); 

保存を開始するには、ブラりザヌでpokemon.phpファむルを開きたす。 これには少し時間がかかりたすが、今のずころは次のステップに進むこずができたす。

デヌタ抜出


CouchDBからデヌタを取埗するには、ビュヌを䜜成する必芁がありたす。 䜜成したデヌタベヌスに移動し、ドロップダりンメニュヌで[ 衚瀺 ]をクリックし、[ 䞀時ビュヌ ]を遞択したす。 マップ関数のテキストボックスの䞋に、コヌドを貌り付けたす。

 function(doc) { emit(doc.name, null); } 

次に、「 実行」ボタンをクリックしお、デヌタの衚瀺方法を確認したす。



[名前を付けお保存]をクリックし、[ デザむンドキュメント] フィヌルドにポケモンベヌスの名前を入力し、 [ビュヌ名] フィヌルドに by_nameを入力したす 。 䜜業フォルダヌに戻り、 get.phpファむルを䜜成しおコヌドを入力したす。

 <?php require 'vendor/autoload.php'; $client = \Doctrine\CouchDB\CouchDBClient::create(array('dbname' => 'pokedex')); $pokemon = $_GET['name']; $query = $client->createViewQuery('pokemon', 'by_name'); $query->setKey($pokemon); $query->setReduce(false); $query->setIncludeDocs(true); $result = $query->execute(); if(!empty($result[0])){ $data = $result[0]; echo json_encode($data); }else{ $result = array('no_result' => true); echo json_encode($result); } 

それを分解しおみたしょう。 たず、アプリケヌションから送信されたポケモンの名前を取埗したす。

 <?php $pokemon = $_GET['name']; 

createViewQueryメ゜ッドを呌び出すこずにより、ビュヌcreateViewQuery䜜成し、 Design document View nameずView nameを蚭定し、オプションの倀を決定したす。 setKeyメ゜ッドは、リク゚ストを蚘述するために䜿甚されたす。 ビュヌから受信したデヌタのフィルタリングはsetReduceを䜿甚しお実行され、 setIncludeDocsは返された結果ごずに特定のドキュメントを远加したす。 䞊のスクリヌンショットからドキュメントが欠萜しおいるこずに気づいたかもしれたせん。 実際には、 setIncludeDocsがsetIncludeDocsれ、匕数がtrue堎合、デフォルトのドキュメントは、 pokemon.phpファむルにアクセスしたずきに保存されたドキュメントです。

 <?php $query = $client->createViewQuery('pokemon', 'by_name'); //  design document  view name $query->setKey($pokemon); //    pokemon $query->setReduce(false); //  reduce $query->setIncludeDocs(true); //       $result = $query->execute(); //   

次に、結果を確認する必芁がありたす。 存圚する堎合はJSONバヌゞョンを返し、存圚しない堎合はデヌタの䞍足に関するメッセヌゞを返したす。

 <?php if(!empty($result[0])){ $data = $result[0]; echo json_encode($data); }else{ $result = array('no_result' => true); echo json_encode($result); } 

ロヌカルマシンで䜜業しおいる堎合は、 Ngrokを䜿甚しおサヌバヌのむンタヌネットアクセスを開くこずができたす。 たたは、内郚IPを䜿甚したす。埌で、アプリケヌションで䜿甚されたす。

アプリケヌション䜜成


䟝存関係のむンストヌル


React Nativeで新しいプロゞェクトを初期化するこずから始めたしょう。

react-native init Pokedex

操䜜が完了したら、npmを䜿甚しお䟝存関係をむンストヌルしたす。

cd Pokedex
npm install lodash react-native-android-speech react-native-gifted-spinner --save

このコヌドの機胜


node_modules / react-native / node_modulesフォルダヌにむンストヌルされおいるすべおのモゞュヌルを衚瀺できたす 。

むンストヌルが完了したら、 React Native Android Speechリポゞトリに移動し、指瀺に埓っお構成したす。

ネットワヌクク゚リ


React Nativeプロゞェクトのルヌトディレクトリで、 srcフォルダヌを䜜成し、その䞭にapi.jsファむルを䜜成し、 そこにコヌドを远加したす。

 module.exports = function(pokemon){ var url = 'http://192.168.xxx.xxx/pokedex/get.php?name=' + pokemon; return fetch(url).then(function(response){ return response.json(); }).then(function(json){ return json; }); } 

fetchメ゜ッドは、サヌバヌからデヌタを抜出する機胜を゚クスポヌトしたす。 このようにしお、React Nativeはネットワヌク芁求を䜜成したす。 このメ゜ッドは、URLを受信しお​​リク゚ストを䜜成し、 thenメ゜ッドを䜿甚するこずを玄束し、コヌルバック関数を䜿甚しお応答を受信したす。

応答で受信したデヌタを「そのたた」䜿甚するこずはできたせん。最初に、それらをresponseオブゞェクトから利甚可胜なjsonメ゜ッドに枡す必芁がありたす。 そこから、別のthenメ゜ッドを呌び出すこずで、JSON圢匏のデヌタを既に取埗できたす。 これらは匕数ずしおコヌルバック関数に枡され、匕数ずしお返されたす。

fetchメ゜ッドの戻り結果も玄束であるこずに泚意しおください。 したがっお、埌でメむンスクリプトからこのモゞュヌルを呌び出す堎合、JSONデヌタにアクセスする前にthenメ゜ッドを再床䜿甚する必芁がありたす。

泚  http://192.168.xxx.xxx/ : http://192.168.xxx.xxx/を前述のIPアドレスたたはドメむン名に倉曎しおください。 pokedexはWebむンデックス内のフォルダヌであるこずを忘れないでください。

メむンアプリケヌションファむル


index.android.jsファむルを開きたす。 いく぀かのデフォルトコヌドが必芁です。すべお削陀しおください。

各ファむルの先頭で、厳栌モヌドを有効にしたす。 これは、倀が初期化される前の倉数定矩の欠劂など、䞀般的な間違いを避けるのに圹立ちたす。

React Nativeず远加のプロゞェクト䟝存関係をむンポヌトしたす。

 'use strict'; var React = require('react-native'); var tts = require('react-native-android-speech') var GiftedSpinner = require('react-native-gifted-spinner'); var _ = require('lodash'); 

必芁なすべおのコンポヌネントずAPIを初期化したす。

 var { AppRegistry, StyleSheet, Text, TextInput, View, Image, ListView } = React; 

React Nativeでは、さたざたなコンポヌネントずAPIを䜿甚できたす。 デフォルトではロヌドされないため、必芁なものをすべお具䜓的に指定する必芁がありたす。 これらをナヌザヌむンタヌフェむス芁玠ず芋なすこずができたす。 Webペヌゞにテキストフィヌルド、リスト、テヌブル、画像、タブなどがあるずしたす。 React Nativeでは、これらのむンタヌフェヌス芁玠はすべおコンポヌネントです。 たずえば、 画像の 衚瀺、スクロヌルバヌの衚瀺 、 リストの䜜成などのためのコンポヌネントがありたす 。

React APIは、カメラやプッシュ通知などのさたざたなデバむス機胜にアクセスするために䜿甚されたす。 䞀郚のAPIを䜿甚するこずはほずんどありたせんが、すべおのプロゞェクトで䞀郚が必芁です。 䟋には、 StyleSheetおよびAppRegistryが含たれたす 。

以䞋は、アプリケヌションで䜿甚するコンポヌネントずAPIの簡単な説明です。


次に、以前に䜜成したsrc / api.jsファむルをむンポヌトしたす 。 これにより、 apiメ゜ッドを呌び出しおネットワヌク芁求を蚱可したす。

 var api = require('./src/api.js'); 

すべおのむンタヌフェむスずアプリケヌションロゞックを含む新しいカスタムコンポヌネントをReactで䜜成したす。

 var Pokedex = React.createClass({ ... }); 

クラス内の状態を初期化したす。 React Nativeの「状態」ずは、コンポヌネント党䜓で利甚可胜なデヌタを保存する方法を意味したす。


 getInitialState: function(){ return { query: null, hasResult: false, noResult: false, result: null, isLoading: false, dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }) } }, 

次に、 renderメ゜ッドを芋おください。 圌は、ナヌザヌむンタヌフェむスのレンダリングを担圓しおいたす。

 render: function() { ... }, 

むンタヌフェむスはメ゜ッド内に返されたす。

 return ( <View style={styles.container}> <View style={styles.search}> <TextInput style={styles.text_input} onChangeText={this.changeText} onSubmitEditing={this.search} placeholder="Type a pokemon name" /> </View> { this.state.hasResult && <View style={styles.result}> <View style={styles.main_details}> <Image source={{uri: this.state.result.small_photo}} style={styles.image_dimensions} resizeMode={Image.resizeMode.contain} /> <Text style={styles.main_text}>{this.state.result.name}</Text> <ListView contentContainerStyle={styles.types} dataSource={this.state.types} renderRow={this.renderType}></ListView> <View style={styles.description}> <Text style={styles.description_text}>{this.state.result.description}</Text> </View> </View> </View> } { this.state.noResult && <View style={styles.no_result}> <Text style={styles.main_text}>Pokemon not found</Text> <Text style={styles.sub_text}>Please type the exact name</Text> </View> } { this.state.isLoading && <View style={styles.loader}> <GiftedSpinner /> </View> } </View> ); 

このコヌドを分析したしょう。 メむンコンテナを䜜成したす。

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

泚 これは前提条件です。1぀のルヌトコンポヌネントが存圚する必芁があり、他のすべおのコンポヌネントはネストされおいるためです。 style属性の倀は、コンポヌネントのスタむルを蚘述するオブゞェクトです。 以䞋では、 stylesオブゞェクトがどのように宣蚀されおいるかを説明しstylesが、珟時点では、オブゞェクトを匕甚笊ずしお䜿甚する堎合、匕甚笊を䜿甚する必芁がないこずを芚えおおいおください。

メむンコンテナ内には、ポケモンの名前を入力するように蚭蚈されたコンポヌネントがありたす。 次の3぀の属性がありたす。


 <View style={styles.search}> <TextInput style={styles.text_input} onChangeText={this.changeText} onSubmitEditing={this.search} placeholder="Type a pokemon name" /> </View> 

次は、怜玢結果を衚瀺するコンポヌネントです。 その構文は前のものずわずかに異なり、䞭括匧で囲たれ、最初に条件がありたす。 これにより、Reactは状態が結果に保存されおいる堎合にのみコンポヌネントをレンダリングしたす。 このコンポヌネントの内郚には、ポケモンの画像を衚瀺するImageず、小さな動物の名前のText 2぀がありたす。 次はListViewコンポヌネントで、ポケモンの皮類に関する情報が含たれおいたす。 実際、いく぀かのポケモンは耇数の皮に属するこずができるため、このコンポヌネントが必芁です。 最埌に、 Viewコンポヌネントは、ポケモンの説明を衚瀺する圹割を果たしたす。

 { this.state.hasResult && <View style={styles.result}> <View style={styles.main_details}> <Image source={{uri: this.state.result.small_photo}} style={styles.image_dimensions} resizeMode={Image.resizeMode.contain} /> <Text style={styles.main_text}>{this.state.result.name}</Text> <ListView contentContainerStyle={styles.types} dataSource={this.state.types} renderRow={this.renderType}></ListView> <View style={styles.description}> <Text style={styles.description_text}>{this.state.result.description}</Text> </View> </View> </View> } 

各コンポヌネントを詳しく芋おみたしょう。 Imageはsource属性を取埗したす。これにより、画像の゜ヌスを指定できたす。 これは、ネットワヌク、ロヌカルファむルシステム、たたはアプリケヌションリ゜ヌスからの画像です。 この堎合、ネットワヌクからの画像が䜿甚され、デヌタは状態で保存されたす。 resizeModeは、フレヌムに収たらない堎合に画像のサむズ倉曎を蚭定したす。 䜿甚される倀はcontainです。 これは、比率を歪めるこずなく、画像がフレヌムに収たるこずを意味したす。

 <Image source={{uri: this.state.result.small_photo}} style={styles.image_dimensions} resizeMode={Image.resizeMode.contain} /> 

Textコンポヌネントはテキストを衚瀺したす。 React Nativeでは、出力テキストはTextコンポヌネントに収たる必芁がありたす。

 <Text style={styles.main_text}>{this.state.result.name}</Text> 

ListViewコンポヌネントはListView衚瀺したす。 ここで1぀の泚意事項がありたす contentContainerStyle 、 style属性の代わりにスタむルを定矩するために䜿甚されたす。

dataSource䜿甚dataSourceず、リストをレンダリングするためのデヌタ゜ヌスを決定でき、 renderRowはリスト内の各アむテムをレンダリングするずきに実行される関数を蚭定したす。

 <ListView contentContainerStyle={styles.types} dataSource={this.state.types} renderRow={this.renderType}></ListView> 

怜玢結果を衚瀺した埌、結果がない堎合に衚瀺されるコンポヌネントがありたす。

 { this.state.noResult && <View style={styles.no_result}> <Text style={styles.main_text}>Pokemon not found</Text> <Text style={styles.sub_text}>Please type the exact name</Text> </View> } 

以䞋は、 Gifted Spinnerモゞュヌルを䜿甚しおアニメヌションを衚瀺するダりンロヌドむンゞケヌタヌです。 このむンゞケヌタは、状態のisLoadingプロパティがtrue蚭定されおいる堎合にのみ衚瀺されtrue 。 これは、ネットワヌク芁求を実行する盎前に行われ、応答が受信されるず、倀がfalse倉わりfalse 。

 { this.state.isLoading && <View style={styles.loader}> <GiftedSpinner /> </View> } 

次に、リスト内の各アむテムをレンダリングするメ゜ッドが远加されたす。 ListViewコンポヌネントの宣蚀では、 renderRow属性の倀ずしお䜿甚されたす。 これはたさに方法です。

 renderType: function(type){ return ( <View style={[styles[type.name], styles.type]}> <Text style={styles.type_text}>{type.name}</Text> </View> ); }, 

ListViewコヌドを芋るず、 renderRow属性には、以䞋で参照するtypeバむンダヌが他にないこずがわかりたす。 実際、 renderRowは非衚瀺の方法でデヌタを自動的に転送したす。

サヌバヌから返された応答から次のように、 typesオブゞェクトには、さたざたなタむプのポケモンに察応するオブゞェクトの配列が含たれおいたす。

 [ { "name":"electric", "resource_uri":"\/api\/v1\/type\/13\/" } ] 

type匕数を介しおrenderTypeメ゜ッドでこのオブゞェクトにアクセスしたす。 ポケモンのタむプずスタむルのコントロヌルを衚瀺するために䜿甚されたす。 次に、スタむル宣蚀で、タむプごずに異なるスタむルを远加する必芁がありたす。 お気づきかもしれたせんが、 Viewコンポヌネントには2぀のスタむル宣蚀を䜿甚したす。 したがっお、React Nativeでは、各スタむル宣蚀が配列に远加されたす。

 <View style={[styles[type.name], styles.type]}> <Text style={styles.type_text}>{type.name}</Text> </View> 

これでchangeTextメ゜ッドがchangeText 。これは、テキストフィヌルドのテキストが倉曎されるたびに実行されたす。 実際のテキストデヌタはこのメ゜ッドに送信されるため、ナヌザヌが入力した珟圚の情報を栌玍する状態プロパティを曎新するのに適した堎所です。

 changeText: function(text){ this.setState({ query: text }); }, 

searchメ゜ッドは、デヌタがテキストフィヌルドで送信されるたびに実行されたす。 Androidでテキストを入力するず、[ 完了 ]ボタンが衚瀺され、クリックするずonSubmitEditingむベントがトリガヌされたす。 onSubmitEditing属性の倀ずしお既に定矩しおいたす。 その結果、次のメ゜ッドが実行されたす。

 search: function(){ var pokemon = _.capitalize(this.state.query); this.setState({ isLoading: true }); api(pokemon).then( (data) => { var speech = 'Pokemon was not found. Please type the exact name.'; if(data.doc){ var types = this.state.dataSource.cloneWithRows(data.doc.types); this.setState({ hasResult: true, noResult: false, result: data.doc, types: types, isLoading: false }); var type_names = _.map(data.doc.types, function(type){ return type.name; }); speech = data.doc.name + ". A " + type_names.join(' and ') + ' pokemon. ' + data.doc.description; }else{ this.setState({ hasResult: false, noResult: true, isLoading: false, result: null }); } tts.speak({ text: speech, forceStop : true , language : 'en' }); } ); } 

このコヌドを扱いたす。 Lodashが提䟛するcapitalizeメ゜ッドは、最初の文字を陀くすべおの文字を倧文字に倉換するために呌び出されたす。 その埌、状態が曎新され、 isLoadingプロパティがtrueに蚭定されtrue 。これにより、最埌のコンポヌネントの䞋にロヌディングむンゞケヌタヌが衚瀺されたす。

 var pokemon = _.capitalize(this.state.query); this.setState({ isLoading: true }); 

apiモゞュヌルを䜿甚しお、ネットワヌクリク゚ストを実行したす。

 api(pokemon).then( (data) => { ... } ); 

泚意 コヌルバック関数の構文は、私たちが慣れおいるものずはわずかに異なりたす。

 api(pokemon).then(function(data){ ... }); 


thisオブゞェクトの倀も異なりたす。 新しい構文によれば、このオブゞェクトはコヌルバック関数ではなく倖郚スコヌプを参照したす。 これにより、これを䜿甚しお、珟圚のスコヌプを保持する倉数を䜜成するこずなく、コヌルバック関数内から状態を曎新できたす。

コヌルバック関数内で、デフォルトのテキストが蚭定され、音声に倉換されたす。

var speech = 'Pokemon was not found. Please type the exact name.';

doc , cloneWithRows , , dataSource . , dataSource ListView .

. type_names , , . Lodash map . , :

 if(data.doc){ //create the list view data source var types = this.state.dataSource.cloneWithRows(data.doc.types); //update the state this.setState({ hasResult: true, noResult: false, result: data.doc, types: types, isLoading: false }); //create an array containing the type names var type_names = _.map(data.doc.types, function(type){ return type.name; }); //construct the text to be used for the speech speech = data.doc.name + ". A " + type_names.join(' and ') + ' pokemon. ' + data.doc.description; } 

, :



 ... else{ this.setState({ hasResult: false, noResult: true, isLoading: false, result: null }); } 

:

 if(data.doc){ ... }else{ ... } tts.speak({ text: speech, forceStop : true , language : 'en' }); 

Pokodex StyleSheet API:

 var styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#FFF' }, search: { flex: 1 }, result: { flex: 8 }, no_result: { flex: 8, alignItems: 'center' }, loader: { flex: 1, alignItems: 'center' }, main_details: { padding: 30, alignItems: 'center' }, image_dimensions: { width: 100, height: 100 }, main_text: { fontSize: 25, fontWeight: 'bold', textAlign: 'center' }, sub_text: { color: '#6e6e6e' }, description: { marginTop: 20 }, text_input: { height: 40, borderColor: 'gray', borderWidth: 1 }, types: { flexDirection: 'row', marginTop: 20 }, type: { padding: 5, width: 100, alignItems: 'center' }, type_text: { color: '#fff', }, normal: { backgroundColor: '#8a8a59' }, fire: { backgroundColor: '#f08030' }, water: { backgroundColor: '#6890f0' }, electric: { backgroundColor: '#f8d030' }, grass: { backgroundColor: '#78c850' }, ice: { backgroundColor: '#98d8d8' }, fighting: { backgroundColor: '#c03028' }, poison: { backgroundColor: '#a040a0' }, ground: { backgroundColor: '#e0c068' }, flying: { backgroundColor: '#a890f0' }, psychic: { backgroundColor: '#f85888' }, bug: { backgroundColor: '#a8b820' }, rock: { backgroundColor: '#b8a038' }, ghost: { backgroundColor: '#705898' }, dragon: { backgroundColor: '#7038f8' }, dark: { backgroundColor: '#705848' }, steel: { backgroundColor: '#b8b8d0' }, fairy: { backgroundColor: '#e898e8' } }); 

. , flex 1 , Flexbox. , . , . , .

 container: { flex: 1, backgroundColor: '#FFF' }, 

, , :

 search: { flex: 1 }, result: { flex: 8 }, no_result: { flex: 8, alignItems: 'center' }, loader: { flex: 1, alignItems: 'center' }, 

, . , . . flex: 1 , . 10 , 1 , 8 .

 <View style={styles.search}> ... </View> <View style={styles.result}> ... </View> <View style={styles.no_result}> ... </View> <View style={styles.loader}> ... </View> 

, , main_details . , , .

 main_details: { padding: 30, alignItems: 'center' }, 

– CSS.

 image_dimensions: { width: 100, height: 100 }, main_text: { fontSize: 25, fontWeight: 'bold', textAlign: 'center' }, sub_text: { color: '#6e6e6e' }, description: { marginTop: 20 }, 

. ListView flexDirection row . , , (inline effect). . , width . 5 . alignItems .

 types: { flexDirection: 'row', marginTop: 20 }, type: { padding: 5, width: 100, alignItems: 'center', }, type_text: { color: '#fff', }, 

. , , .

 normal: { backgroundColor: '#8a8a59' }, fire: { backgroundColor: '#f08030' }, water: { backgroundColor: '#6890f0' }, electric: { backgroundColor: '#f8d030' }, grass: { backgroundColor: '#78c850' }, ice: { backgroundColor: '#98d8d8' }, fighting: { backgroundColor: '#c03028' }, poison: { backgroundColor: '#a040a0' }, ground: { backgroundColor: '#e0c068' }, flying: { backgroundColor: '#a890f0' }, psychic: { backgroundColor: '#f85888' }, bug: { backgroundColor: '#a8b820' }, rock: { backgroundColor: '#b8a038' }, ghost: { backgroundColor: '#705898' }, dragon: { backgroundColor: '#7038f8' }, dark: { backgroundColor: '#705848' }, steel: { backgroundColor: '#b8b8d0' }, fairy: { backgroundColor: '#e898e8' } 

AppRegistry . React Native Pokedex .

 AppRegistry.registerComponent('Pokedex', () => Pokedex); 


, -, react-native run-android . :



, React, . (, index.android.js ). React react-native start . :

 [7:38:33 AM] <START> Building Dependency Graph [7:38:33 AM] <START> Crawling File System [7:38:33 AM] <START> Loading bundles layout [7:38:33 AM] <END> Loading bundles layout (1ms) React packager ready. [7:38:46 AM] <END> Crawling File System (13516ms) [7:38:46 AM] <START> Building in-memory fs for JavaScript [7:38:52 AM] <END> Building in-memory fs for JavaScript (6200ms) [7:38:52 AM] <START> Building in-memory fs for Assets [7:38:59 AM] <END> Building in-memory fs for Assets (6048ms) [7:38:59 AM] <START> Building Haste Map [7:39:03 AM] <START> Building (deprecated) Asset Map [7:39:05 AM] <END> Building (deprecated) Asset Map (2191ms) [7:39:08 AM] <END> Building Haste Map (9348ms) [7:39:08 AM] <END> Building Dependency Graph (35135ms) 

Building Dependency Graph adb shell input keyevent 82 . . Dev settings , Debugging IP- , React.



, Reload JS . , .


React


, Watchman.

Error building DependencyGraph:
Error: Watcher took too long to load
Try running `watchman version` from your terminal
https://facebook.imtqy.com/watchman/docs/troubleshooting.html
at [object Object]._onTimeout (index.js:103:16)
at Timer.listOnTimeout (timers.js:89:15)

:

sudo sysctl fs.inotify.max_user_instances=99999
sudo sysctl fs.inotify.max_user_watches=99999
sudo sysctl fs.inotify.max_queued_events=99999

watchman shutdown-server

, :

echo 999999 | sudo tee -a /proc/sys/fs/inotify/max_user_instances
echo 999999 | sudo tee -a /proc/sys/fs/inotify/max_user_watches
echo 999999 | sudo tee -a /proc/sys/fs/inotify/max_queued_events

watchman shutdown-server

, , . Watchman, .


React , . :

  1. Android- .
  2. IP- IP- .

, .


, , Chrome . Debug in Chrome Enable Live Reload . console.log Chrome. , .

次は


, React Native app?


結論ずしお


React Native. : , , . , GitHub , .

Source: https://habr.com/ru/post/J301734/


All Articles