使用react-navigation進行簡單的跳轉+底部導航欄+側拉框的配置

使用react native進行開發,不可避免的會使用到跳轉。鑑於目前react native版本問題。一般使用react-navigation實現跳轉。這也是官方推薦使用的組件。

createStackNavigator  爲您的應用提供一種在屏幕之間轉換的方式,其中每個新屏幕都放置在堆棧頂部。這個是我們實現跳轉所要使用到的API。它的用法

createStackNavigator(RouteConfigs, StackNavigatorConfig);

RouteConfigs參數,我們用來寫路由相關的配置。一般我們寫具有跳轉關係的View配置。比如,有A、B、C三個頁面,我需要A、B、C三個頁面同時具有跳轉關係。即我可以從A跳轉至B,亦可以從A跳轉至C,B跳轉至C等同級跳轉。我們將A、B、C註冊到RouteConfigs參數,同時,我們可以對這些頁面進行一些樣式操作。默認頁面會有標題欄,返回按鈕等樣式。如果不需要,我們可以將其去除等操作。總而言之,我們可以用來註冊我們期望具有跳抓功能的View頁面

StackNavigatorConfig參數,用來設置一些跳轉的默認操作,比如堆棧的默認屏幕視圖,初始路線的參數等設置,按照需求進行設置,不過多做講解。

const HomeStack = createStackNavigator({//設置HomeScreen頁面與SettingView頁面的跳轉註冊
  HomeScreen: {
    screen: HomeScreen,//註冊View頁面名稱
    navigationOptions: () => ({
      header: null, //去除標題欄
      headerBackTitle: null, //去除返回按鈕
      gesturesEnabled: true  //是否可以使用手勢來關閉此屏幕。在iOS上默認爲true,在Android上默認爲false
    })
  },
  SettingView: {//註冊設置頁面
    screen: SettingView,
    navigationOptions: () => ({
      header: null, //去除標題欄
      headerBackTitle: null, //去除返回按鈕
      gesturesEnabled: true  //是否可以使用手勢來關閉此屏幕。在iOS上默認爲true,在Android上默認爲false
    })
  },
  MapScreen: {//註冊地圖頁面
    screen: MapScreen,
    navigationOptions: () => ({
      header: null, //去除標題欄
      headerBackTitle: null, //去除返回按鈕
      gesturesEnabled: true  //是否可以使用手勢來關閉此屏幕。在iOS上默認爲true,在Android上默認爲false
    })
  },
  DetailInfo: {//註冊業務詳情頁面
    screen: DetailInfo,
    navigationOptions: () => ({
      header: null, //去除標題欄
      headerBackTitle: null, //去除返回按鈕
      gesturesEnabled: true  //是否可以使用手勢來關閉此屏幕。在iOS上默認爲true,在Android上默認爲false
    })
  },
  Appointment: {//註冊業務列表頁面
    screen: Appointment,
    navigationOptions: () => ({
      header: null, //去除標題欄
      headerBackTitle: null, //去除返回按鈕
      gesturesEnabled: true  //是否可以使用手勢來關閉此屏幕。在iOS上默認爲true,在Android上默認爲false
    })
  }
},{
  initialRouteName:'HomeScreen',
  initialRouteParams:{ //設置初始參數
    key:'aaaaa',
    key1:'bbbbb'
  },
});

注意:createStackNavigator與createSwitchNavigator的區別。它兩個作用大致相同。createStackNavigator具有堆棧功能,createSwitchNavigator不具有堆棧功能,createSwitchNavigator的目的是一次只顯示一個屏幕。默認情況下,它不處理後退操作,並在您切換時,將路由重置爲其默認狀態。這是我們從身份驗證流程中想要的確切行爲。

我們進行了跳轉配置後,當然就是如何使用了。

screen您應用中的每個組件都會navigation自動提供道具。prop包含各種便利功能,用於在路由的路由器上分派導航操作。

進行跳轉的API https://reactnavigation.org/docs/en/navigation-prop.html

this.props.navigation
    navigate - 轉到另一個屏幕,找出它需要採取的行動
    goBack - 關閉活動屏幕並向後移動
    addListener - 訂閱導航生命週期的更新
    isFocused- true如果屏幕聚焦false則返回的功能
    state - 當前路線
    setParams - 改變路線的參數,傳遞參數
    getParam - 獲得具有後備的特定參數,獲取參數
    dispatch - 向路由器發送動作
    dangerouslyGetParent - 返回父導航器的函數(如果有)

簡單舉例

我們可以使用this.props.navigation.navigate('要跳轉的View名稱')方式進行跳轉,該跳轉方式,會將跳轉的頁面存入棧頂部,當點擊返回按鍵,或者調用this.props.navigation.goBack()方法時返回到上個頁面。

我們如果想要回退到指定的頁面,我們需要得到我們將要回退頁面上一個頁面的頁面key進行回退,調用this.props.navigation.goBack(key)方式回退到指定的頁面。

比如,有A、B、C、D四個頁面。我從A使用this.props.navigation.navigate('B')跳轉到了B頁面,然後使用this.props.navigation.navigate('C')跳轉到了C頁面,然後又跳轉到D頁面,但是我想直接返回到A頁面,如果我按返回鍵,則返回順序是D > C > B > A。不是我想要的結果。我如果之間使用this.props.navigation.navigate('A')的方式跳轉到A,那麼我退出時,會出現A > D > C > B > A。這種情況(當然,有雙擊退出,強制退出操作不在考慮範圍內),設計不太合理。我們可以使用this.props.navigation.goBack(key)這種方式進行返回,我們首先要得到我們要返回的頁面的前一個頁面的頁面KEY,也就是A前面的頁面B頁面的KEY。

let HOME_KEY = this.props.navigation.state.key;//得到當前頁面key

使用以上方式得到頁面key後傳入到D頁面中的this.props.navigation.goBack(key)函數中。我們就能夠返回到原頁面。

使用this.props.navigation.navigate()方法也可以進行傳值。

this.props.navigation.navigate('A', {
                    session: this.state.session,
                    ucid: this.state.ucid,
                });

取值,包括初始化頁面時的傳遞的初始值,也可以以這種方式取值

 const { navigation } = this.props;
        let value = navigation.getParam('key', '');  //得到Drawer頁面傳遞的頁面key
        let value1 = navigation.getParam('key1', '');  //得到Drawer頁面傳遞的頁面key

底部導航欄 createBottomTabNavigator  react-navigation爲我們提供了底部導航欄與頂部導航欄的API,我們只做底部導航欄的講解。

createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);

它同樣有兩個參數。RouteConfigs用法與createStackNavigator用法一樣,不做講解。但是,我們會將底部導航所需的View放在次參數中,因爲,底部導航至少會有兩個頁面。

{//RouteConfigs
  Home: {
    screen: HomeStack,
  },
  Work: {
    screen: WorkStack,
  },
}

BottomTabNavigatorConfig,我們用來做一些底部導航欄樣式的一些操作,比如,我們所點擊的圖標,圖標顏色(選中狀態顏色,未選中狀態顏色),圖標下方的字體等等。都在代碼中添加了註釋

//配置底部導航欄(標籤欄),HomeScreen與WorkScreen頁面
const bottomTabNavigator = createBottomTabNavigator({//RouteConfigs
  Home: {
    screen: HomeStack,
  },
  Work: {
    screen: WorkStack,
  },
}, {//BottomTavNavtigtorConfig
    defaultNavigationOptions: ({ navigation }) => ({ //用於屏幕的默認導航選項
      tabBarIcon: ({ focused, tintColor }) =>   //設置圖標
        getTabBarIcon(navigation, focused, tintColor),
      tabBarLabel: navigation.state.routeName === 'Home' ? '首頁' : '工作',  //設置圖標下方的字體
    }),
    tabBarOptions: { //設置圖標的樣式
      activeTintColor: '#1E90FF',  //活動選項卡的標籤和圖標顏色。選中時顏色
      inactiveTintColor: '#979797'  //非活動選項卡的標籤和圖標顏色。 未選中時顏色
    },
  });


//設置底部圖片以及圖片的狀態改變
const getTabBarIcon = (navigation, focused, tintColor) => {  //設置圖標默認狀態
  const { routeName } = navigation.state;
  if (routeName === 'Home') { //設置點擊Home頁面時,圖標狀態
    return <Image style={{  //圖標的樣式
      width: 25,
      height: 25
    }}
      source={focused ? require('./image/tabbar_home_pressed.png') : require('./image/tabbar_home.png')} />  //返回選中與未選中不同狀態時,圖標的樣式,顏色
  } else if (routeName === 'Work') { //設置點擊Work頁面時,圖標狀態
    return <Image style={{ ////圖標的樣式
      width: 25,
      height: 25
    }}
      source={focused ? require('./image/tabbar_msg_pressed.png') : require('./image/tabbar_msg.png')} />  //返回選中與未選中不同狀態時,圖標的樣式,顏色
  }
};

側拉框 createDrawerNavigator  

createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig);

同樣的,倆個參數RouteConfigs, DrawerNavigatorConfig。

RouteConfigs

路由CONFIGS對象是從路由名稱映射到一個路由配置,它告訴導航以呈現該路線什麼。我們一般用來寫側拉框所在的頁面。

{//RouteConfigs
  Set: {//Set是固定名稱
    screen: bottomTabNavigator,
  },
}

DrawerNavigatorConfig,用來配置側拉框抽屜的一些默認設置

{
    order: ['Set'],//routeNames數組,用於定義抽屜項目的順序。
    initialRouteName: 'Set',//初始路由的routeName。
    drawerLockMode: 'unlocked',//設置是否響應手勢
    //'unlocked'   可以通過手勢和代碼 打開關閉抽屜
    //'locked-closed' 抽屜關閉狀態  不能通過手勢打開  只能通過代碼實現
    //'locked-open'  抽屜打開狀態  不能通過手勢關閉  只能通過代碼實現

    drawerWidth: 300, //抽屜的寬度或返回的功能。
    drawerPosition: 'left', //選項是left或right。默認是left位置。
    useNativeAnimations: true, //啓用原生動畫。默認是true。
    drawerBackgroundColor: '#FAFAFA', //使用抽屜背景獲取某種顏色。默認是white。
    //用於呈現抽屜內容的組件,例如導航項。收到navigation抽屜的道具。默認爲DrawerItems
    //用於自定義
    contentComponent: props => {
      return <Drawer {...props} />;
    },
    //配置抽屜內容  items相關
    contentOptions: {
      // items: [OtherScreen],//可以修改或覆蓋路由數組  不知道幹嘛用的
      // activeItemKey: 'AppInfo', //識別活動路線的關鍵  也不知道幹嘛用的
      activeTintColor: 'white', //活動標籤的標籤和圖標顏色
      activeBackgroundColor: 'blue', //活動標籤的背景顏色
      inactiveTintColor: 'black', //非活動標籤的標籤和圖標顏色
      inactiveBackgroundColor: 'red', //非活動標籤的背景顏色

      // //按下項目時要調用的函數 不知道是否使用錯誤 一直沒反應
      //github上面有答案 在自定義視圖的時候 會有用
      // onItemPress(route) {
      //     console.log('onItemPress'+route);
      // },

      // itemsContainerStyle: '', //內容部分的樣式對象
      // itemStyle: '', //單個項目的樣式對象,可以包含圖標和 / 或標籤
      // labelStyle: '', //Text當標籤是字符串時,樣式對象在內容部分內覆蓋樣式
      // activeLabelStyle: '', //Text當標籤是字符串(與之合併labelStyle)時,樣式對象覆蓋活動標籤的樣式
      // inactiveLabelStyle: '', //Text當標籤是字符串(與之合併labelStyle)時,樣式對象覆蓋非活動標籤的樣式
      // iconContainerStyle: '', //樣式對象以覆蓋View圖標容器樣式。
    }

  }

重點:

//用於自定義
    contentComponent: props => {
      return <Drawer {...props} />;
    },

我們用該方法,可以將抽屜視圖進行自定義。也就是說。我們可以在此頁面編寫抽屜視圖。Drawer就是我的抽屜頁面的視圖。完全可以按照自己想要的效果進行佈局。

this.props.navigation.openDrawer();//打開抽屜
this.props.navigation.closeDrawer();//關閉抽屜

我們可以在抽屜所在的頁面中調用以上方法,進行打開或者關閉抽屜的動作。當然,也可以滑動屏幕來打開或關閉抽屜。

關於react-navigation的使用,我還遠遠未發掘出來,這只是它的一部分,包括它的生命週期,與RN的生命週期的對應,對於它的生命週期的處理。不過,這已經足夠開發出一個優秀的App了。希望以後會更加熟練的使用react-navigation吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章