翻譯|React-navigation導航系統(1)


title: 翻譯|React-navigation(1)
date: 2017-03-27 20:26:48
categories: 翻譯


這個React-native的導航系統可能已經基本官方標配系統了.兩個月時間已經積累了3000多的star.
教程可以參考這篇文章,這個文章作者老兄和我一樣很喜歡折騰.前面就參考了他的另一個導航教程,這次再來.


本文是翻譯的官方文檔.打算翻譯完
基本思路是有幾個注冊系統,如果要在app中使用導航,必須要把組件注冊到對應的系統中.

原文開始:你好!移動導航

使用React Navigation來構建跨平臺導航

配置和安裝

首先要配置React Native系統.接下來創建RN項目,添加react-navigation

 # Create a new React Native App
 #創建新RN APP
react-native init SimpleApp
cd SimpleApp

# Install the latest version of react-navigation from npm安裝最新版本
npm install --save react-navigation

# Run the new app運行,確保初始化正常
react-native run-android # or:
react-native run-ios
初始化界面
初始化界面

為了在Android和iOS之間共享代碼,刪除掉index.ios.jsindex.andorid.js的實際代碼,使用import './App'來實現具體的代碼

現在來創建‘App.js’

Stack Navigator介紹

為了想使用stack navigation的概念,我們會使用StactkNavigator.(譯注:stack就是數據結構的堆棧技術,遵循后進先出的原理).每一個到導航的screen(導航畫面)被放在堆棧的棧頂,返回時候,會從棧頂彈出對應的組件.先看看一個screen的情況

//其實這個代碼沒有實現App.js,export的模式,注意
import React from 'react';
import {
  AppRegistry,
  Text,
} from 'react-native';
//導入stack導航組件
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',//在導航中顯示的標題內容
  };
  render() {
    //這里可以是導入的其他組件
    return <Text>Hello, Navigation!</Text>;
  }
}
//進行導航的注冊
const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
});

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

title是staticnavigationOptions里配置的標題內容,出現的界面看下面

添加新的導航畫面

再添加一個ChatScreen畫面

 class ChatScreen extends React.Component {
  static navigationOptions = {
    title: 'Chat with Lucy',
  };
  render() {
    return (
      <View>
        <Text>Chat with Lucy</Text>
      </View>
    );
  }
}

HomeScreen中添加一個button組件,使用routeName Chat關聯到ChatScreen.

 class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello, Chat App!</Text>
        <Button
          onPress={() => navigate('Chat')}
          title="Chat with Lucy"
        />
      </View>
    );
  }
}

我們正在使用從screen navigation prop獲得的導航函數轉向ChatScreen.但是這需要在StackNavigator中注冊.

 const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
  Chat: { screen: ChatScreen },//新添加的screen
});

現在可以導航到ChatScreen,也可以返回了.


傳遞參數

ChatScreen中硬編碼標題不是好辦法,可以在導航的時候傳遞參數.首先編輯一下HomeScreen組件,傳遞name參數到路由中.

 class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello, Chat App!</Text>
        <Button
          onPress={() => navigate('Chat', { user: 'Lucy' })}
          title="Chat with Lucy"
        />
      </View>
    );
  }
}

我們可以編輯ChatScreen組件顯示的name參數,這個參數通過route來傳遞.

 class ChatScreen extends React.Component {
  static navigationOptions = {
    // Nav options can be defined as a function of the navigation prop:
    title: ({ state }) => `Chat with ${state.params.user}`,
  };
  render() {
    // The screen's current route is passed in to `props.navigation.state`:
    const { params } = this.props.navigation.state;
    return (
      <View>
        <Text>Chat with {params.user}</Text>
      </View>
    );
  }
}

現在當你導航到Chat screen的時候,可以看到名字了.在HomeScreen中改變name,看看變化.

巢式導航

在移動應用中組合各種形式的導航是非常普遍的.React Navigation中的router和navigators是組合式的,如此以來可以允許我們定義非常復雜的導航系統.

Tab Navigator的介紹

我們在App.js中創建TabNavigator

 class RecentChatsScreen extends React.Component {
render() {
  return <Text>List of recent chats</Text>
}
}

class AllContactsScreen extends React.Component {
render() {
  return <Text>List of all contacts</Text>
}
}

const MainScreenNavigator = TabNavigator({
Recent: { screen: RecentChatsScreen },
All: { screen: AllContactsScreen },
});

如果MainScreenNavigation作為頂層的導航組件來渲染,看起來是這個樣子的:

在屏幕中構造一個巢式導航器

我們想讓這些tabs在app的第一屏顯示,但是堆棧中的新的screen會覆蓋tabs.
在前一步驟設置的StackNavigator中添加tabs作為頂級導航

 const SimpleApp = StackNavigator({
  Home: { screen: MainScreenNavigator },
  Chat: { screen: ChatScreen },
});

因為MainScreenNavigator作為screen,可以傳遞navigationOtions參數:

 MainScreenNavigator.navigationOptions = {
  title: 'My Chats',
};

在每一個tabs中添加鏈接到chat的按鈕:

 <Button
  onPress={() => this.props.navigation.navigate('Chat', { user: 'Lucy' })}
  title="Chat with Lucy"
/>

現在我們在每個導航器彼此之間做了配置,可以在導航界面之間切換.

配置頭部

在前面的例子中,我們用StactNavigator創建了幾個screen.
當我們導航到chat screen,我們通過navigate 函數傳遞特定的參數到新的導航界面.例如,我們想給chat screen提供一個人名:

 this.props.navigation.navigate('Chat', { user:  'Lucy' });

user參數可以在chat screen中獲取到:

 class ChatScreen extends React.Component {
  render() {
    const { params } = this.props.navigation.state;
    return <Text>Chat with {params.user}</Text>;
  }
}

設定頭部標題

接著來,可以在screen 參數中配置頭部的標題

 class ChatScreen extends React.Component {
  static navigationOptions = {
    // // Title may be a simple string:
    // title: 'Hello',
     
    // Or the title string may be a function of the 
    navigation prop:可以是prop的函數解析
    title: ({ state }) => `Chat with ${state.params.user}`
  };
  ...
}

添加右側的按鈕

可以在option中添加定制的右側按鈕

static navigationOptions = {
  header: {
    right: <Button title="Info" />,
  },
  ...

title一樣,headeroption可以定義為prop的一個函數.讓我們來基于導航參數渲染一個不同的按鈕,設定為點擊時調用navigation.setParams:

static navigationOptions = {
  title: ({ state }) => {
    if (state.params.mode === 'info') {
      return `${state.params.user}'s Contact Info`;
    }
    return `Chat with ${state.params.user}`;
  },
  header: ({ state, setParams }) => {
    // The navigation prop has functions like setParams, goBack, and navigate.
    let right = (
      <Button
        title={`${state.params.user}'s info`}
        onPress={() => setParams({ mode: 'info' })}
      />
    );
    if (state.params.mode === 'info') {
      right = (
        <Button
          title="Done"
          onPress={() => setParams({ mode: 'none' })}
        />        
      );
    }
    return { right };
  },
  ...

現在頭部可以和screen的路由state進行交互了.



第一部分就這些.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容