ReactNative系列(五):react-natigation 3.x全解(中)

ReactNative.jpg

ReactNative整理:《ReactNative系列》

內(nèi)容目錄

1顷蟆、navigationOptionsAppContainer
2伦腐、導(dǎo)航器屬性參數(shù)
3洞渔、StackNavigator用法詳解
4漂羊、SwitchNavigator用法詳解
5蹬屹、BottomTabNavigator用法詳解
6侣背、DrawerNavigator用法詳解
7白华、結(jié)語


一、navigationOptionsAppContainer

AppContainer:負(fù)責(zé)管理應(yīng)用的state并將頂層的navigator鏈接到整個應(yīng)用環(huán)境贩耐。創(chuàng)建各種navigator時弧腥,已經(jīng)將要用到的頁面整合到一起,并生成了一個導(dǎo)航組件潮太,但是該組件并沒有接入到應(yīng)用中管搪,所以需要AppContainer將導(dǎo)航組件包裹,同時鏈接到整個應(yīng)用環(huán)境铡买,這樣生成的導(dǎo)航器就可以使用了抛蚤。

1、關(guān)于createAppContainer的簡單示例:

import { createAppContainer, createStackNavigator } from 'react-navigation';

const StackControllers = createStackNavigator({
  // 路由配置對象
}, {
  // 導(dǎo)航屬性配置
});

// 將生成的導(dǎo)航器組件 StackControllers 包裹到 Container 中
const StackContainer = createAppContainer(StackControllers);

// 現(xiàn)在 StackContainer 變成了 React 渲染的主要組件
export default StackContainer;

2寻狂、React Native 中的 createAppContainer prop:

<StackContainer
   onNavigationStateChange={this.handleNavigationChange()}
   uriPrefix={'/app'}
/>
  • onNavigationStateChange(prevState, newState, action)
    每當(dāng)導(dǎo)航器管理的navigation state 發(fā)生變化時岁经,都會調(diào)用該函數(shù)。它接收之前的 state蛇券、navigation 的新 state 以及發(fā)布狀態(tài)更改的 action缀壤。 默認(rèn)情況下,它將 state 的更改打印到控制臺纠亚。
  • uriPrefix
    應(yīng)用可能會處理的URI前綴塘慕,在處理深度鏈接以提取傳遞給路由器的路徑時使用。

navigationOptions:導(dǎo)航器內(nèi)部頁面的選項配置蒂胞⊥寄兀可以在導(dǎo)航器RouteConfigsNavigatorConfig中配置;也可以在頁面中配置骗随。優(yōu)先級為:RouteConfigs配置 > 頁面中navigationOptions配置 > NavigatorConfig配置蛤织。
以StackNavigator為例:

// 導(dǎo)航器中配置
const StackControllers = createStackNavigator({
  stack1: {
    screen: StackController1,
    navigationOptions: () => ({
      title: 'controller1'
    })
  },
  stack2: {
    screen: StackController2
  }
}, {
  initialRouteName: 'stack1',
});
// 頁面中配置 navigationOptions
export default class StackController1 extends Component {
  static navigationOptions = {
    title: 'StackController1'
  };
  ...
}

如果RouteConfigs中和頁面中都存在navigationOptions,則以RouteConfigs中的配置為準(zhǔn)鸿染。
navigationOptions是用來配置頁面頭部或者手勢等屬性的指蚜,RouteConfigs和頁面中靜態(tài)配置,是針對單個頁面的涨椒;而在XXNavigatorConfig中配置摊鸡,則是針對導(dǎo)航內(nèi)所有screen生效。

二蚕冬、 導(dǎo)航器屬性參數(shù)

1免猾、Navigation prop reference

應(yīng)用中的每個頁面組件都會自動提供navigation prop,該屬性包含便捷的方法用于觸發(fā)導(dǎo)航操作囤热,如下所示:

  • this.props.navigation
    • navigate - 跳轉(zhuǎn)到另一個屏幕猎提,計算出需要執(zhí)行的操作
    • goBack - 關(guān)閉活動屏幕并在堆棧中向后移動
    • addListener - 訂閱導(dǎo)航生命周期的更新
    • isFocused - 如果屏幕獲取焦點(diǎn),函數(shù)返回true赢乓,否則返回false
    • state - 當(dāng)前state忧侧,路由狀態(tài)
    • setParams - 更改路由的參數(shù)
    • getParam - 獲取具有回退功能的特定參數(shù)
    • dispatch - 向路由發(fā)送action
    • dangerouslyGetParent - 返回父級navigator的函數(shù)

重點(diǎn)是要強(qiáng)調(diào)navigation屬性不會傳遞給所有組件石窑;只有screen頁面組件會自動收到此屬性。

2蚓炬、Navigator-dependent functions

this.props.navigation上有些取決于當(dāng)前navigator的附加函數(shù)
如果是StackNavigator松逊,除了navigategoBack,還提供了如下方法:

  • this.props.navigation
    • push - 推一個新的路由到堆棧
    • pop - 返回堆棧中的上一個頁面
    • popToTop - 跳轉(zhuǎn)到堆棧中最頂層的頁面
    • replace - 用新路由替換當(dāng)前路由
    • reset - 擦除整個導(dǎo)航狀態(tài)肯夏,并將其替換為多個操作的結(jié)果
    • dismiss - 關(guān)閉當(dāng)前堆棧

如果是DrawerNavigator经宏,則還可以使用以下選項:

  • this.props.navigation
    • openDrawer - 打開
    • closeDrawer - 關(guān)閉
    • toggleDrawer - 切換,如果是打開則關(guān)閉驯击,反之亦然

三烁兰、StackNavigator用法詳解

堆棧式導(dǎo)航:提供一種在每個新屏幕放置在堆棧頂部的屏幕之間轉(zhuǎn)換的方法。該導(dǎo)航器是以棧的形式管理頁面徊都,每新建一個頁面都會壓入棧中沪斟,最新創(chuàng)建的頁面在棧頂。默認(rèn)情況下的配置具有熟悉的Android和iOS外觀&效果:iOS上從右側(cè)滑入暇矫,Android上從底部淡入主之。
StackNavigator配置代碼示例:

/**
 * 堆棧導(dǎo)航:
 * 將頁面配置到導(dǎo)航器中,不能跳轉(zhuǎn)到導(dǎo)航?jīng)]有配置的頁面
 * @type {NavigationContainer}
 */
const StackControllers = createStackNavigator({
  // RouteConfig 配置
  stack1: {
    screen: StackController1,
    navigationOptions: {
      title: 'Controller1',
      headerStyle: {
        backgroundColor: '#ffffff'
      }
    }
  },
  stack2: {
    screen: StackController2,
    navigationOptions: {
      title: '頁面2'
    }
  },
  stack3: {
    screen: StackController3
  },
  stack4: {
    screen: StackController4
  }
}, { // 
  initialRouteName: 'stack1',
  defaultNavigationOptions: {
    headerStyle: {
      backgroundColor: 'grey',
    },
    headerTintColor: 'blue',
    headerTitleStyle: {
      fontSize: 20,
    },
  }
});

const StackContainer = createAppContainer(StackControllers);

export default StackContainer;

RouteConfig - 配置的頁面必須含有screen屬性值李根,用來定義頁面標(biāo)識槽奕;navigationOptions用來初始化頁面的一些配置,例如:Header樣式房轿,手勢等粤攒。
需要注意的是:
StackNavigatorConfig - 配置中用的是defaultNavigationOptions控制導(dǎo)航內(nèi)所有頁面Header展示;用navigationOptions配置沒有效果囱持,react-navigation版本號是3.8.1夯接,各位同學(xué)可以自己嘗試下。
initialRouteName屬性值是配置導(dǎo)航器的默認(rèn)頁面洪唐;在沒有設(shè)置的情況下钻蹬,默認(rèn)為RouteConfig中配置的第一個頁面。
頁面代碼:

/**
 * 展示頁面
 * 跳轉(zhuǎn)方法:handleOnPress
 * 返回方法:backPress
 */
export default class StackController2 extends Component {
  constructor(props) {
    super(props);
    this.handleOnPress = this.handleOnPress.bind(this);
  }

  componentDidMount() {
    console.log('-did-mount-stack2--');
  }

  componentWillUnmount() {
    console.log('-un-mount-stack2--');
  }

  /* 點(diǎn)擊跳轉(zhuǎn)到第三個頁面 stack3 */
  handleOnPress() {
    this.props.navigation.navigate('stack3');
  }

  /* 點(diǎn)擊返回上層頁面 */
  backPress() {
    this.props.navigation.goBack();
  }
  
  render() {
    return(
      <View style={pageStyle.container}>
        <Text
          style={pageStyle.contentText}
          onPress={this.handleOnPress}
        >
          Controller2 To Controller3
        </Text>
        <Text
          style={pageStyle.backText}
          onPress={this.backPress}
        >
          返回
        </Text>
      </View>
    );
  }
}

看過ReactNative官方文檔的同學(xué)應(yīng)該知道:
常用的點(diǎn)擊事件組件有TouchableOpacity凭需、ButtonText,它們都包含onPress屬性肝匆,可以調(diào)用點(diǎn)擊方法粒蜈。我這里用的是Text組件實現(xiàn)點(diǎn)擊切換頁面和頁面返回。
StackNavigator的頁面創(chuàng)建與跳轉(zhuǎn)相對比較簡單旗国,比較麻煩的是多層頁面的關(guān)閉枯怖。這里給出幾種多層頁面退出的解決辦法:
例如:從A -> B -> C -> D頁面,要從D返回到A
1能曾、利用頁面key
導(dǎo)航器中每個頁面都包含navigation屬性值度硝,可以通過this.props.navigation取到肿轨,該屬性中有許多方法和數(shù)據(jù),其中包括state蕊程。在state中包含key椒袍、routeNameparamskey - 是頁面在導(dǎo)航器中的唯一標(biāo)識ID,根據(jù)這個標(biāo)識能找到對應(yīng)頁面藻茂;routeName - 是當(dāng)前頁面在導(dǎo)航器中配置的路由名稱驹暑;params - 傳遞的參數(shù),是由上一個頁面?zhèn)魅搿?br> ?注意:從D返回到A辨赐,用到的是B頁面的key值优俘,而不是A的。

 /**
   * 點(diǎn)擊跳轉(zhuǎn)到第三個頁面 stack3
   * 其中 B: navigate.state.key 為傳遞的參數(shù)
   */
  handleOnPress() {
    const navigate = this.props.navigation;
    navigate.navigate('stack3', {
      B: navigate.state.key
    });
  }

可以用類似的代碼結(jié)構(gòu)做出四個頁面掀序,測試跳轉(zhuǎn)和返回帆焕。

/**
   * 最后一個頁面的點(diǎn)擊事件
   * 點(diǎn)擊返回到A頁面
   */
  handleOnPress() {
    const navigate = this.props.navigation;
    navigate.goBack(navigate.state.params.B);
  }

這樣,在點(diǎn)擊最后一個頁面的文本時不恭,就能返回到A頁面视搏,而且沒有多余的退棧動畫。
2县袱、攔截路由actionstate改變
createStackNavigator關(guān)聯(lián)到的源碼:創(chuàng)建時傳遞兩個參數(shù)生成的是NavigationContainer浑娜,而該NavigationContainer是個接口,包含router屬性式散。繼續(xù)向下查看源碼發(fā)現(xiàn)router的value值是NavigationRouter筋遭,其中有導(dǎo)航調(diào)用的方法,getStateForAction就是我們需要用到的,它能監(jiān)聽交互的action和導(dǎo)航的state档悠。下面摘出來源碼:

...
// 堆棧導(dǎo)航的創(chuàng)建
export function createStackNavigator(
  routeConfigMap: NavigationRouteConfigMap,
  stackConfig?: StackNavigatorConfig
): NavigationContainer;
...

// NavigationContainer接口及屬性
export interface NavigationContainer extends React.ComponentClass<
      NavigationContainerProps & NavigationNavigatorProps<any>
    > {
    new (
      props: NavigationContainerProps & NavigationNavigatorProps<any>,
      context?: any
    ): NavigationContainerComponent;

    router: NavigationRouter<any, any>;
    screenProps: ScreenProps;
    navigationOptions: any;
    state: { nav: NavigationState | null };
}

// NavigationRouter -- 導(dǎo)航路由接口
export interface NavigationRouter<State = NavigationState, Options = {}> {
    /**
     * The reducer that outputs the new navigation state for a given action, with
     * an optional previous state. When the action is considered handled but the
     * state is unchanged, the output state is null.
     */
    getStateForAction: (
      action: NavigationAction,
      lastState?: State
    ) => State | null;

    /**
     * Maps a URI-like string to an action. This can be mapped to a state
     * using `getStateForAction`.
     */
    getActionForPathAndParams: (
      path: string,
      params?: NavigationParams
    ) => NavigationAction | null;

    getPathAndParamsForState: (
      state: State
    ) => {
      path: string;
      params?: NavigationParams;
    };

    getComponentForRouteName: (routeName: string) => NavigationComponent;

    getComponentForState: (state: State) => NavigationComponent;

    /**
     * Gets the screen navigation options for a given screen.
     *
     * For example, we could get the config for the 'Foo' screen when the
     * `navigation.state` is:
     *
     *  {routeName: 'Foo', key: '123'}
     */
    getScreenOptions: NavigationScreenOptionsGetter<Options>;
}

了解依據(jù)之后藏姐,來修改我們自己的代碼:

// 定義攔截器,用來將修改的action和state作為新的數(shù)據(jù)傳入
const StackInterceptor = StackControllers.router.getStateForAction;
/**
 * 攔截思路:
 *  1响驴、過濾action,只有是 action.type === 'Navigation/BACK' 時攔截處理
 *  2撕蔼、根據(jù)攔截到的action中的key值豁鲤,在state.routes中找到對應(yīng)數(shù)據(jù)
 *  3、找到的對應(yīng)的route數(shù)據(jù)下標(biāo)index鲸沮,取 index + 1 的數(shù)據(jù)的key值賦給 action.key
 *  4琳骡、把新修改的 action 和 state 傳入定義好的攔截器中
 */
StackControllers.router.getStateForAction = (action, state) => {
  console.log(action, '---action--');
  console.log(state, '---state--');
  let nextAction = action;
  if (state && action && action.type === 'Navigation/BACK') {
    const routeLength = state.routes.length;
    const isExist = state.routes.findIndex(route => action.key === route.routeName);
    if (isExist > -1 && isExist + 1 <= routeLength) {
      nextAction = {
        ...action,
        key: state.routes[isExist + 1].key
      };
    }
    console.log(nextAction, '--nextAction--');
    console.log(state, '--nextstate---');
  }
  return StackInterceptor(nextAction, state);
};

該方法中,我們用到的goBack方法能直接傳遞導(dǎo)航器中配置的路由名稱為參數(shù)讼溺。例如:this.props.navigation.goBack('stack1')楣号。同樣的,返回A頁面用到的還是B頁面的Key值,所以在攔截查找位置的時候要取到stack1的下標(biāo)index的下一個位置index + 1的數(shù)據(jù)才行炫狱。
依據(jù)同樣的方法藻懒,可以通過修改state.routes的數(shù)據(jù)來實現(xiàn)由D -> A,我們通過日志可以看到 B视译、C嬉荆、D三個頁面的componentWillUnmount方法都沒有執(zhí)行,雖然頁面仍然能創(chuàng)建跳轉(zhuǎn)和關(guān)閉憎亚,但是畢竟影響了組件的生命周期员寇,所以不推薦大家使用。修改action.keystate.routes都能達(dá)到相同的效果第美,但建議使用前者更穩(wěn)妥蝶锋。

另:其實還可以通過修改源碼方法實現(xiàn)多層頁面返回。3.x版本之前可以通過修改react-navigation源碼的StackRouter.js中針對action.type === NavigationActions.BACK修改返回方式什往;但是3.x之后版本光修改該文件不生效了扳缕,還需要修改別的地方(還在摸索)。而且開發(fā)中會碰到有些問題需要刪除node_modules文件夾重新npm install的情況别威,這時node_modules文件夾會重置躯舔,需要再重新修改react-navigation源碼,很麻煩省古,所以建議大家不要修改源碼粥庄。

四、SwitchNavigator用法詳解

SwitchNavigator的用途是一次只顯示一個頁面豺妓。 默認(rèn)情況下惜互,它不處理返回操作,并在你切換時將路由重置為默認(rèn)狀態(tài)琳拭。項目中我們時常會碰到進(jìn)入應(yīng)用時展示啟動頁训堆、廣告頁或者校驗身份的需求,而且這些頁面展示一次后就不再返回白嘁。此時就可以用SwitchNavigator來實現(xiàn)坑鱼。

const SwitchControllers = createSwitchNavigator({
  switch1: { // 廣告頁面或者身份驗證頁面
    screen: SwitchController1
  },
  switch2: { // 主頁面
    screen: SwitchController2
  }
}, {
  initialRouteName: 'switch1',
  resetOnBlur: true,
  backBehavior: 'none'
});

export default SwitchContainer = createAppContainer(SwitchControllers);

SwitchNavigator單獨(dú)使用局限性比較大,往往適合與別的導(dǎo)航器嵌套使用:比如絮缅,示例中的SwitchController1和SwitchController2都可以用其他類型導(dǎo)航器代替鲁沥,其中可以包含多個頁面。

需要注意的屬性有兩個:

  • resetOnBlur - 用來標(biāo)識切換離開屏幕時是否需要重置所有嵌套的導(dǎo)航器狀態(tài)盟蚣,默認(rèn)值是true黍析。
  • backBehavior - 設(shè)置后退按鈕是否會導(dǎo)致標(biāo)簽切換到初始路由,如果是屎开,設(shè)置為initialRoute;否則為none。默認(rèn)是none奄抽。

SwitchNavigator可以實現(xiàn)切換路由后蔼两,返回鍵不能回到上一個頁面的功能,在某些特定情況下可以使用該特質(zhì)逞度。

五额划、BottomTabNavigator用法詳解

TabNavigator標(biāo)簽導(dǎo)航是我們最常見的一種導(dǎo)航樣式,在3.x中將TabNavigator被移除档泽,改用BottomTabNavigatorMaterialTopTabNavigator俊戳,兩者類似。這里只對前者進(jìn)行講解馆匿。
還是和其他導(dǎo)航器創(chuàng)建一樣抑胎,需要兩個參數(shù)配置對象。

const tab_home_select = require('../../../resource/tabbar_home_select.png');
const tab_home = require('../../../resource/tabbar_home.png');
const tab_list_select = require('../../../resource/tabbar_list_select.png');
const tab_list = require('../../../resource/tabbar_list.png');
const tab_self_select = require('../../../resource/tabbar_self_select.png');
const tab_self = require('../../../resource/tabbar_self.png');

const BottomTabControllers = createBottomTabNavigator({
  Home: {
    screen: TabHomeController,
    navigationOptions: {
      title: '首頁',
      tabBarLabel: '首頁',
      tabBarIcon: ({ focused, horizontal, tintColor }) => (
        <Image
          source={focused ? tab_home_select : tab_home}
          style={{ width: 20, height: 20 }}
          resizeMode={'contain'}
        />
      )
    }
  },
  List: {
    screen: TabListController,
    navigationOptions: {
      title: '書單',
      tabBarLabel: '書單',
      tabBarIcon: ({ focused, horizontal, tintColor }) => (
        <Image
          source={focused ? tab_list_select : tab_list}
          style={{ width: 20, height: 20 }}
          resizeMode={'contain'}
        />
      ),
      // tabBarOnPress: ({navigation, defaultHandler}) => {
      //   console.log(navigation, '--navigation--');
      //   console.log(defaultHandler, '--defaultHandler--');
      // }
    }
  },
  Self: {
    screen: TabMineController,
    navigationOptions: {
      title: '我的',
      tabBarLabel: '我的',
      tabBarIcon: ({ focused, horizontal, tintColor }) => (
        <Image
          source={focused ? tab_self_select : tab_self}
          style={{ width: 20, height: 20 }}
          resizeMode={'contain'}
        />
      )
    }
  }
}, {
  lazy: true,
  initialRouteName: 'Home',
  order: ['Home', 'List', 'Self'],
  tabBarOptions: {
    activeTintColor: '#FF8800',
    inactiveTintColor: '#666666',
    showIcon: true,
    labelStyle: {
      fontSize: 12
    },
    style: {
      backgroundColor: 'white',
      height: 45
    }
  }
});

有幾個比較重要的屬性這里需要提一下:

  • tabBarIcon - 該方法中有三個參數(shù):
    • focused - 當(dāng)前Tab是否獲取焦點(diǎn)渐北,如果是我們一般都會設(shè)置當(dāng)前Tab高亮阿逃;
    • horizontal - 當(dāng)前是否橫屏,如果橫屏為true赃蛛,否則為false;
    • tintColor - 對應(yīng)activeTintColorinactiveTintColor恃锉,如果獲取焦點(diǎn)則為activeTintColor設(shè)置的rgba色值字符串,否則為inactiveTintColor呕臂;如果沒有設(shè)置則返回默認(rèn)色值破托。
  • lazy - 是否懶加載。和原生一樣歧蒋,懶加載除了能提高渲染性能之外土砂,還可以提升交互體驗。
  • order - 底部Tab 的位置疏尿,是在左側(cè)還是中間瘟芝,都可以通過這個屬性調(diào)整。
  • tabBarOptions - 設(shè)置TabBar的一些屬性:激活與非激活狀態(tài)下的顏色褥琐、是否顯示圖標(biāo)或者圖標(biāo)文本樣式等锌俱。

有個特殊屬性可以對Tab的點(diǎn)擊進(jìn)行監(jiān)測:
tabBarOnPress - 用來添加自定義邏輯處理,該方法在切換到下一個頁面之前調(diào)用敌呈,包含的參數(shù)可以直接用一個event表示贸宏,或者可以拆分成navigationdefaultHandler
方法中需要調(diào)用defaultHandler()磕洪,否則會頁面切換失效吭练。

// 兩個參數(shù)navigation、defaultHandler
tabBarOnPress: ({navigation, defaultHandler}) => {
   defaultHandler();
}

// 一個event參數(shù)
tabBarOnPress: (event) => {
   event.defaultHandler();
}

六析显、DrawerNavigator用法詳解

DrawerNavigator抽屜式導(dǎo)航也是常見導(dǎo)航類型之一鲫咽,原生應(yīng)用中經(jīng)常會見到 -- 由側(cè)滑菜單來控制頁面跳轉(zhuǎn)。但是一個應(yīng)用肯定會有不少頁面,如果都用側(cè)滑菜單來控制的話分尸,不僅混亂锦聊,而且體驗也不是很好,所以抽屜式導(dǎo)航往往是與別的導(dǎo)航器嵌套使用的箩绍。

const DrawerControllers = createDrawerNavigator({
  Main: {
    screen: DrawerMainController,
  },
  List: {
    screen: DrawerListController,
  },
  Self: {
    screen: DrawerSelfController,
  },
  Setting: {
    screen: DrawerSettingController,
  }
}, {
  drawerWidth: 300,
  drawerPosition: 'left',
  initialRouteName: 'Main',
  order: ['Main', 'List', 'Self', 'Setting'],
  drawerLockMode: 'locked-closed',
  drawerType: 'slide',
  contentComponent: (props) => {
    console.log(props, '--props--');
    return (
      <ScrollView style={{flex: 1}}>
        <SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
          <DrawerItems {...props}/>
        </SafeAreaView>
      </ScrollView>
    );
  },
  contentOptions: {
    activeTintColor: '#FF8800',
    inactiveTintColor: '#666666',
  }
});

export default DrawerContainer = createAppContainer(DrawerControllers);

其中有幾個比較重要的屬性需要注意:

  • drawerIcon - 側(cè)滑item的圖標(biāo)孔庭,在頁面的各自navigationOptions中配置。會回傳兩個參數(shù):focused 狀態(tài)是否選中標(biāo)識材蛛;tintColor item選中時的色值圆到。
  • drawerLockMode - 設(shè)置抽屜的鎖定模式:unlocked,是默認(rèn)值卑吭,用手勢可以打開和關(guān)閉抽屜芽淡;locked-closed,鎖定關(guān)閉陨簇,在抽屜保持關(guān)閉的狀態(tài)下吐绵,用手勢不能打開;locked-open河绽,鎖定打開己单,在抽屜打開的狀態(tài)下,用手勢不能關(guān)閉抽屜耙饰。
  • contentComponent - 該屬性是用來設(shè)置側(cè)滑內(nèi)容組件的纹笼,可以自定義組件樣式,默認(rèn)情況下為DrawerItems(該組件可以從react-navigation中導(dǎo)入)苟跪。方法中會傳遞props屬性給item組件廷痘,通過打印可以查看里面包含的值以及方法(選其中幾個,大部分比較好理解):
    • activeItemKey - 是當(dāng)前選中頁面的key值標(biāo)簽
    • items - 抽屜的路由數(shù)組件已,可以修改或覆蓋笋额。其中元素為頁面路由對象state值,包含key篷扩、routeNameparams三個參數(shù)
    • descriptors - 我理解為描述元兄猩,里面包含抽屜頁面的常用屬性值,例如:key鉴未、navigation枢冤、stateoptions(這個不知道具體用處)
  • contentOptions - 內(nèi)容選項,用來設(shè)置item的屬性值铜秆。
    • activeTintColor - 當(dāng)前選項卡的標(biāo)簽和圖標(biāo)顏色
    • inactiveTintColor - 非當(dāng)前選項卡的標(biāo)簽和圖標(biāo)顏色
    • onItemPress - 當(dāng)item被點(diǎn)擊時調(diào)用
    • itemStyle - 子組件item的樣式

七淹真、結(jié)語

??以上是對幾個導(dǎo)航器的拆分理解,其中的屬性只是挑出了一部分连茧,比較重要核蘸、難理解或者典型的巍糯,并不是全部。剩余的需要大家自己去對照上一篇嘗試或者log日志輸出對比值纱,這里就不再挨個講解了鳞贷。相信自己動手嘗試過的肯定要記憶更深坯汤,理解也更透徹虐唠。
??單個導(dǎo)航理解以后,它們的優(yōu)缺點(diǎn)也就有了基本的認(rèn)識惰聂,之后就是各種搭配組合使用了疆偿。多個導(dǎo)航嵌套能實現(xiàn)更復(fù)雜的業(yè)務(wù)需求,也能提高交互體驗搓幌。

??下一篇:ReactNative系列(六):react-natigation 3.x全解(下)

?如果有不對的地方歡迎指出杆故,大家互相討論,如果喜歡請點(diǎn)贊關(guān)注

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末溉愁,一起剝皮案震驚了整個濱河市处铛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拐揭,老刑警劉巖撤蟆,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異堂污,居然都是意外死亡家肯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門盟猖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讨衣,“玉大人,你說我怎么就攤上這事式镐》凑颍” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵娘汞,是天一觀的道長歹茶。 經(jīng)常有香客問我,道長价说,這世上最難降的妖魔是什么辆亏? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮鳖目,結(jié)果婚禮上扮叨,老公的妹妹穿的比我還像新娘。我一直安慰自己领迈,他們只是感情好彻磁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布碍沐。 她就那樣靜靜地躺著,像睡著了一般衷蜓。 火紅的嫁衣襯著肌膚如雪累提。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天磁浇,我揣著相機(jī)與錄音斋陪,去河邊找鬼。 笑死置吓,一個胖子當(dāng)著我的面吹牛无虚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衍锚,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼友题,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了戴质?” 一聲冷哼從身側(cè)響起度宦,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎告匠,沒想到半個月后戈抄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凫海,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年呛凶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片行贪。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡漾稀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出建瘫,到底是詐尸還是另有隱情崭捍,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布啰脚,位于F島的核電站殷蛇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏橄浓。R本人自食惡果不足惜粒梦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荸实。 院中可真熱鬧匀们,春花似錦、人聲如沸准给。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至祖灰,卻和暖如春钟沛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背局扶。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工恨统, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人详民。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓延欠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沈跨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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