React-native 嘗鮮計劃-情境切換(Navigator)

來源:互聯網
上載者:User
 
在上篇文章《react-native 嘗鮮計劃-環境搭建》中講述了react-native 的環境搭建,並初始化了 react-native 的第一個項目。如果你已經完成了上一篇文章的學習,並且成功調試第一個 “hello world” 項目,你已成功地經邁出第一步,接下來的學習就會順利得多。在我成功調試出第一個項目之後,連蒙帶差的走讀了下原生代碼和 index.android.js 代碼,腦海裡有很多疑問,第一個疑問就是:react-native 如何做多個頁面跳轉的。相信你也一樣,帶著帶著問題來學習是比較有動力的一種學習方式。
切換情境demo

本章重點是 demo,react-native情境切換的demo下載地址:https://github.com/liuguangli/RN-DemoForChangeSence。

先跑出效果,從現象到本質符合人類的一般認知規律,建議讀者下載demo自行研究,我也希望你研究demo之後不用讀後文了。


Navigator 熱身

 react-natvie 中來切換頁面的一個重要組件就是Navigator,這裡只介紹demo中用到的幾個重要的屬性和方法,詳細的可以點擊這裡可以看官方文檔介紹。

1 initialRoute

 Navigator 的一個屬性,用來描述Navigator情境棧中的第一個情境資訊route。一個結構類型,一個般要提供 name,index等描述資訊。

2 renderSence

 Navigator 的一個方法,在Navigator建立或 push(route) /pop()方法調用的時候回調renderSence(route, navigator)方法,出入兩個參數:route和 navigator 本身。

3 push

  情境跳轉:指定一個route, 在回調方法 renderSence()中根據 route 返回指定的 sence,sence可以是任何可視化組件或容器。 

4 pop

 回退到上一個情境。


一步一步的來實現這個demo

1. 入口(index.android.js)

 我們先完成 react 的第一個入口組件,將其註冊到到 app上。

 首先引入我們要使用的組建:

 

var React = require('react-native');var {  AppRegistry,  Navigator,} = React; 


AppRegistry,用於註冊我們的程式入口組件。Navigator,是我們使用的第一個組件,用於操作環境轉換。

建立組件:


// 建立入口組件var ChangeSenceProject = React.createClass({  render: function() {    var initialRoute = {name:"A"};    return (<Navigator      initialRoute={initialRoute}     renderScene={RouteMapper}     />)  },});
註冊到應用:
//註冊項目AppRegistry.registerComponent('ChangeSenceProject', () => ChangeSenceProject);
注意到我們在  ChangeSenceProject 的入口方法 render 中使用 Navigator 組件,並且提供第一個route對象: {name:"A"}和一個renderSence方法,這個方法必須要實現,所以我們要在 React.createClass 之前先實現renderSence方法,我們方法名定義為: RouteMapper
//Navigator跳轉規則var RouteMapper = function(route,navigation,onComponent){   //todo ,根據route 返回相應的情境};

這裡我門不實現邏輯,等我門完成兩個情境頁面的編寫再來實現這裡的邏輯。

2. Android native

我們使用 ReactRootView 來承載我們的互動組件。

main_activity.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MoviesApp">    <com.facebook.react.ReactRootView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/react_root_view"/></RelativeLayout>
MainActivity.java
package com.changesence;import android.app.Activity;import android.os.Bundle;import android.view.KeyEvent;import com.facebook.react.LifecycleState;import com.facebook.react.ReactInstanceManager;import com.facebook.react.ReactRootView;import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;import com.facebook.react.shell.MainReactPackage;public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {    private ReactInstanceManager mReactInstanceManager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mReactInstanceManager = ReactInstanceManager.builder()                .setApplication(getApplication())                .setBundleAssetName("index.android.bundle")                .setJSMainModuleName("index.android")                .addPackage(new MainReactPackage())                .setUseDeveloperSupport(true)                .setInitialLifecycleState(LifecycleState.RESUMED)                .build();        ((ReactRootView) findViewById(R.id.react_root_view))                .startReactApplication(mReactInstanceManager, "ChangeSenceProject", null);    }    @Override    public boolean onKeyUp(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {            mReactInstanceManager.showDevOptionsDialog();            return true;        }        return super.onKeyUp(keyCode, event);    }    @Override    protected void onPause() {        super.onPause();        if (mReactInstanceManager != null) {            mReactInstanceManager.onPause();        }    }    @Override    protected void onResume() {        super.onResume();        if (mReactInstanceManager != null) {            mReactInstanceManager.onResume(this);        }    }    @Override    public void onBackPressed() {        if (mReactInstanceManager != null) {            mReactInstanceManager.onBackPressed();        } else {            super.onBackPressed();        }    }    @Override    public void invokeDefaultOnBackPressed() {        super.onBackPressed();    }}

注意:startReactApplication()方法的第一個參數必須和我們在 AppRegistry 中註冊的項目名一樣。
到此為止,項目可以運行起來了,不過你看到的是空白頁面,因為RouteMapper還沒有任何實現,我們需要提供情境邏輯。

3 . 情境A(SenceA.js)

在情境A中我們只做簡單的顯示一行文字,然後點擊文字跳轉到情境B。

直接上代碼:SenceA.js

'use strict';var React = require('react-native');var {  TouchableNativeFeedback,  Navigator,  StyleSheet,  Text,  View,} = React;var SenceA = React.createClass({  //touch事件回調 touch: function(target:Object){  this.props.navigator.push(   {    title:"B",    name:"B"   }   ); }, render: function() { return (<View style={styles.container}>      <TouchableNativeFeedback       onPress={this.touch}>       <View>         <Text>' this is SenceA,click to SenceB'</Text>       </View>        </TouchableNativeFeedback>       </View>); },});var styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: '#F5FCFF',  },});//匯出情境,供外部requiremodule.exports = SenceA;

4 情境B

情境比和情境A一樣,顯示內容不一樣。直接上代碼:SenceB.js


'use strict';var React = require('react-native');var {  TouchableNativeFeedback,  Navigator,  StyleSheet,  Text,  View,} = React;var SenceB = React.createClass({ touch: function(target:Object){   if (this.props.navigator.getCurrentRoutes().length>1) {    this.props.navigator.pop();   };   }, render: function() { return (<View style={styles.container}>      <TouchableNativeFeedback       onPress={this.touch}>       <View>         <Text>' this is sence B,click to sence A'</Text>       </View>        </TouchableNativeFeedback>       </View>); },});var styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: '#FFFC00',  },});module.exports = SenceB;
5 在 index.android.js 引入情境,完善RouteMapper邏輯。

引入情境:

//引入情境檔案var SenceA = require('./SenceA');var SenceB = require('./SenceB');
完善 RouteMapper:

//Navigator跳轉規則var RouteMapper = function(route,navigation,onComponent){   _navigator = navigation;    if (route.name === 'A') {      console.log("return SenceA");      return (       <SenceA navigator={navigation} />      );    } else if (route.name==="B"){      console.log("return SenceB");      return (        <SenceB navigator={navigation} />      );    } };


武器準備


如果 react-navtive 是行動裝置 App開發的另一個戰場的話,那麼走到這裡我們算是已經知道戰場在哪裡了,接下來事就是怎麼操練武器了。要熟悉react-native的編程,我門先要掌握以下武器:

1 js基礎

2 node.js

3 jsx 文法

4 flexbox布局

註:react-native 出來不久文檔資料不多,文章不足之處歡迎指正,一起研究新技術、新思想。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.