04 ReactNavigation入門詳解(參照官網(wǎng)文檔)(上)

以下內(nèi)容參照StackNavigator官網(wǎng)文檔 鏈接

Hello React Navigation

  1. 參照官網(wǎng),如果要支持安卓架忌,要先下載react-navigation這個庫,在工程路徑下執(zhí)行:
npm install --save react-navigation
// 如果安裝了yarn 也可以使用以下命令
yarn add react-navigation
  1. React Navigation中用到了StackNavigator我衬,即創(chuàng)建了一個類似于瀏覽器的歷史棧的對象叹放。StackNavigator和web歷史棧的一個關鍵區(qū)別是可以手勢和動畫效果。

  2. 創(chuàng)建基本導航棧

import React from 'react';
import { View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
      </View>
    );
  }
}

export default StackNavigator({
  Home: {   // 這個名字任意
    screen: HomeScreen, // 必須有screen這個組件
  },
});

因為StackNavigator()返回一個組件挠羔,所以可以直接通過export導出井仰。顯示這個棧中的內(nèi)容更,目前只有一個空的導航破加,和中間的文字俱恶。
在ReactNative中,在App.js中export的組件是整個App的入口(或者叫根組件),通常不會直接導出一個'導航棧'組件速那,而是用另外一個組件渲染'導航棧'組件。修改如下:

const RootStack = StackNavigator({
  Home: {
    screen: HomeScreen,
  },
});

export default class App extends React.Component {
  render() {
    return <RootStack />;
  }
}
  1. 添加第二屏
class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Details Screen</Text>
      </View>
    );
  }
}

const RootStack = StackNavigator(
  {
    Home: {
      screen: HomeScreen,
    },
    Details: {
      screen: DetailsScreen,
    },
  },
  {
    initialRouteName: 'Home',
  }
);

第一個參數(shù)尿背,表示導航棧內(nèi)有哪些視圖;第二個是配置參數(shù)(可選)
修改initialRouteName后面的名稱端仰,可以發(fā)現(xiàn)初始化的頁面不同。
下節(jié)討論如何在雙屏間切換田藐。

雙屏間切換

  1. 在主屏設置Button荔烧,并添加點擊,關聯(lián)到this.props.navigation.navigate('Details')
import React from 'react';
import { Button, View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

this.props.navigation,這個屬性會被設置到所有StackNavigator中的頁面
navigate('Details'),將頁面名稱傳入該方法汽久,可以跳轉(zhuǎn)到指定頁面
只能跳轉(zhuǎn)到StackNavigator中的界面鹤竭,如果該名稱傳入錯誤,什么也不會發(fā)生景醇。
如果在Details頁面再添加一個Button跳轉(zhuǎn)到Details頁面臀稚,頁面會一直被添加。

  1. StackNavigator會在非首屏提供一個返回箭頭三痰,提供返回操作吧寺。也可以通過添加按鈕關聯(lián)goback返回。此外散劫,StackNavigator自動關聯(lián)了安卓的返回鍵稚机,點擊設備的返回鍵也可以返回。
class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Details Screen</Text>
        <Button 
          title = 'GO TO DETAIL AGAIN'
          onPress = {()=>this.props.navigation.navigate('Details')}         
        />
        <Button
          title="Go back"
          onPress={() => this.props.navigation.goBack()}
        />
      </View>
    );
  }
}

測試發(fā)現(xiàn)获搏,自己設置返回正常赖条,但點擊頭部箭頭返回在MX4上很慢,并不是不執(zhí)行常熙,但是要間隔很久纬乍,實測用了12s。症概。蕾额。目前沒有找到原因。(看看自定義能不能解決)
運行時遇到一個Unknown error: not all success patterns were matched錯誤彼城,重新加載也不行诅蝶,直接運行也不行。 用命令行跑了一下募壕,發(fā)現(xiàn)找不到設備调炬。。舱馅。重新拔插了一下usb就好了缰泡。

傳遞參數(shù)

  1. 通過在調(diào)用navigate方法時傳入一個對象
this.props.navigation.navigate('RouteName', { /* params go here */ })
  1. 讀取參數(shù)
this.props.navigation.state.params
class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
        <Button
          title="Go to Details"
          onPress={() => {
            /* 1. Navigate to the Details route with params */
            this.props.navigation.navigate('Details', {
              itemId: 86,
              otherParam: 'anything you want here',
            });
          }}
        />
      </View>
    );
  }
}

class DetailsScreen extends React.Component {
  render() {
    /* 2. Read the params from the navigation state */
    const { params } = this.props.navigation.state;
    const itemId = params ? params.itemId : null;
    const otherParam = params ? params.otherParam : null;

    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Details Screen</Text>
        <Text>itemId: {JSON.stringify(itemId)}</Text>
        <Text>otherParam: {JSON.stringify(otherParam)}</Text>
        <Button
          title="Go to Details... again"
          onPress={() => this.props.navigation.navigate('Details')}
        />
        <Button
          title="Go back"
          onPress={() => this.props.navigation.goBack()}
        />
      </View>
    );
  }
}

自定義header bar

  1. 每個組件有一個靜態(tài)屬性叫navigationOptions,可以通過這個配置一些參數(shù),例如title (ios默認會居中棘钞,android居左)
class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Home',
  };
  /* render function, etc */
}

class DetailsScreen extends React.Component {
  static navigationOptions = {
    title: 'Details',
  };
  /* render function, etc */
}
  1. 將this.props放入navigationOptions中使用看起來很方便缠借,但因為這是個靜態(tài)屬性,所以實際上并不會關聯(lián)到任何實例宜猜,自然也不會有props屬性泼返。這里需要將navigationOptions變成一個方法,React Navigation會通過一個包含{navigation, navigationOptions, screenProps}的對象調(diào)用它姨拥。

  2. 傳遞參數(shù)設置navigationOptions

class DetailsScreen extends React.Component {
  static navigationOptions = ({ navigation }) => {
    // 注意params是帶大括號的
    const { params } = navigation.state;
    
    return {
      title: params ? params.otherParam : 'A Nested Details Screen',
    }
  };

  /* render function, etc */
}

The argument that is passed in to the navigationOptions function is an object with the following properties:
navigation - The navigation prop for the screen, with the screen's route at navigation.state.
screenProps - The props passing from above the navigator component(上層組件傳過來的參數(shù))
navigationOptions - The default or previous options that would be used if new values are not provided
上面只用到了navigation屬性

  1. 在當前屏幕對navigationOptions進行更新
<Button
    title="Update the title"
    onPress={() => this.props.navigation.setParams({otherParam: 'Updated!'})}
  />

通過setParams設置了一個新的對象

  1. 調(diào)整頭部樣式
    主要用到三個屬性

headerStyle:設置包裹頭部view的樣式绅喉,可以設置背景顏色
headerTintColor: 渲染返回鍵、標題的顏色叫乌。
headerTitleStyle: 設置文字柴罐、字體、粗細(fontWeight)憨奸?

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Home',
    headerStyle: {
      backgroundColor: '#f4511e',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold',
    },
  };

  /* render function, etc */
}

這種設置方式只對當前頁面有效革屠。

  1. 如果要配置對所有導航頁都有效的樣式,應該在StackNavigator的第二個參數(shù)中配置
const RootStack = StackNavigator(
  {
    Home: {
      screen: HomeScreen,
    },
    Details: {
      screen: DetailsScreen,
    },
  },
  {
    initialRouteName: 'Home',
    /* The header config from HomeScreen is now here */
    navigationOptions: {
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  }
);

這樣所有的樣式就一樣了膀藐,如果某個頁面要設置特殊樣式屠阻,可以單獨設置。也可以通過將公共的navigationOptions 通過對象傳入進行修改额各。

  1. 自定義一個組件作為標題
// 定義一個標題
class LogoTitle extends React.Component {
  render() {
    return (
      <Text style ={ {flex:1, fontSize:30,color:'green',textAlign:'center'}}>
      標題
      </Text>
    );
  }
}

class HomeScreen extends React.Component {
 
  static navigationOptions = {
    // title: 'Home',
    headerTitle:<LogoTitle/>,
  };
  ...以下省略...

相關API可以查看StackNavigator reference

代碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末国觉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子虾啦,更是在濱河造成了極大的恐慌麻诀,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傲醉,死亡現(xiàn)場離奇詭異蝇闭,居然都是意外死亡,警方通過查閱死者的電腦和手機硬毕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門呻引,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吐咳,你說我怎么就攤上這事逻悠。” “怎么了韭脊?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵童谒,是天一觀的道長。 經(jīng)常有香客問我沪羔,道長饥伊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮琅豆,結(jié)果婚禮上愉豺,老公的妹妹穿的比我還像新娘。我一直安慰自己茫因,他們只是感情好粒氧,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著节腐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摘盆。 梳的紋絲不亂的頭發(fā)上翼雀,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音孩擂,去河邊找鬼狼渊。 笑死,一個胖子當著我的面吹牛类垦,可吹牛的內(nèi)容都是我干的狈邑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蚤认,長吁一口氣:“原來是場噩夢啊……” “哼米苹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砰琢,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蘸嘶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后陪汽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體训唱,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年挚冤,在試婚紗的時候發(fā)現(xiàn)自己被綠了况增。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡训挡,死狀恐怖澳骤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舍哄,我是刑警寧澤宴凉,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站表悬,受9級特大地震影響弥锄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一籽暇、第九天 我趴在偏房一處隱蔽的房頂上張望温治。 院中可真熱鬧,春花似錦戒悠、人聲如沸熬荆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卤恳。三九已至,卻和暖如春寒矿,著一層夾襖步出監(jiān)牢的瞬間突琳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工符相, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拆融,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓啊终,卻偏偏與公主長得像镜豹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蓝牲,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容