国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

react-navigation使用詳解

stonezhu / 1783人閱讀

摘要:導航組件使用詳解注意了,如果有小伙伴們發現運行作者提供的示例項目報如下的錯誤,可能是大家使用了命令導致的,解決這個錯誤的辦法就是將刪除,然后重新使用命令來安裝,最后使用來起服務,應該就不報錯了。

react-navigation導航組件使用詳解

注意了,如果有小伙伴們發現運行作者提供的react-navigation示例項目報如下的錯誤,可能是大家使用了 yarn install 命令導致的,解決這個錯誤的辦法就是將nodemodules刪除,然后重新使用npm install 命令來安裝,最后使用 npm start 來起服務,應該就不報錯了。如果還有報錯,請加作者交流群,將問題反饋到群里,謝謝。

RN技術總結

作者React Native開源項目OneM地址(按照企業開發標準搭建框架完成開發的):https://github.com/guangqiang-liu/OneM (歡迎小伙伴們 star)

作者簡書主頁:包含60多篇RN開發相關的技術文章http://www.jianshu.com/u/023338566ca5 (歡迎小伙伴們:多多關注多多點贊)

作者React Native QQ技術交流群:620792950 歡迎小伙伴進群交流學習

友情提示:在開發中有遇到RN相關的技術問題,歡迎小伙伴加入交流群(620792950),在群里提問、互相交流學習。交流群也定期更新最新的RN學習資料給大家,謝謝支持!

前言
react-navigation 組件是官方推薦使用的導航組件,功能和性能都遠遠的優于之前的Navigator組件,公司的RN項目最早是使用的react-native-router-flux導航組件,因為那個時候react-navigation 組件還沒有出來,在使用了react-navigation后,感覺比react-native-router-flux組件有更加強大的功能,體驗也略好些,這兩個導航組件是目前star最多的導航組件,并且他們都完美的支持與Redux框架的結合使用,推薦小伙伴們兩個組件都嘗試使用下。
react-navigation官方地址

react-navigation

react-navigation Demo地址

https://github.com/guangqiang-liu/react-navigation-demo

Demo示例講解包含三部分

react-navigation中最常用的基礎用法講解

react-navigation中StackNavigator與TabNavigator和DrawerNavigator的混合嵌套使用

react-navigation與Redux框架結合使用示例

Demo效果圖

注意: 有小伙伴說Demo運行報錯,這里大家需要注意,Demo clone下來之后,我們先要執行 npm install 操作, 然后在執行 react-native link,最后在 執行 npm start 來運行項目,如果還有其他的報錯信息,歡迎進群提出報錯信息

對Redux用法不熟悉的同學們,請看作者的Redux入門講解

http://www.jianshu.com/p/faa98d8bd3fa

react-navigation 主要組成

react-navigation 組件主要由三大部分組成

StackNavigator:類似于iOS中的UINavigationController,頂部的導航欄,主要用于頁面間的跳轉

TabNavigator:類似于iOS中的UITabBarController,底部的tabBar選項卡,主要用于在同一tab下的不同頁面的切換

DrawerNavigator:類似于iOS中常用的抽屜功能,抽屜導航欄

下面我們對react-navigation詳解也主要圍繞這三個API來展開

StackNavigator

StackNavigator導航欄的工作原理就和iOS中原生的UINavigationController一樣的,是以棧的方式來管理每一個頁面控制器的,當使用push就是入棧,當使用pop操作時就是出棧,這個很好理解,如果我們想讓一個頁面控制器有導航欄,那么我們首先要做的就是給這個頁面注冊導航

API

StackNavigator(RouteConfigs, StackNavigatorConfig)

StackNavigator函數中有兩個參數:

RouteConfigs

StackNavigatorConfig

配置RouteConfigs

const RouteConfigs = {
  Home: {
    screen: TabBar // screen屬性為必須配置屬性
  },
  Home2: {
    screen: Home2,
    path:"app/Home2",
    navigationOptions: {
      title: "這是在RouteConfigs中設置的title",
      headerTitleStyle: {
        fontSize: 10
      }
    }
  },
  Home3: { screen: Home3 },
  Home4: { screen: Home4 },
  Home5: {screen: Home5},
  Home6: {screen: Home6},
  Home7: {screen: Home7},
  Setting2: {screen: Setting2},
  Setting3: {screen: Setting3},
}

配置StackNavigatorConfig

const StackNavigatorConfig = {
  initialRouteName: "Home",
  initialRouteParams: {initPara: "初始頁面參數"},
  navigationOptions: {
    title: "標題",
    headerTitleStyle: {fontSize: 18, color: "red"},
    headerStyle: {height: 49},
  },
  paths: "page/main",
  mode: "card",
  headerMode: "screen",
  cardStyle: {backgroundColor: "#ffffff"},
  transitionConfig: (() => ({
  })),
  onTransitionStart: (() => {
    console.log("頁面跳轉動畫開始")
  }),
  onTransitionEnd: (() => {
    console.log("頁面跳轉動畫結束")
  }),
}

注冊導航

import {StackNavigator, TabNavigator} from "react-navigation"

const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

export default class Main extends Component {
    render() {
        return (
            
        )
    }
}

從上面注冊導航的代碼塊中,我們可以看出StackNavigator函數接受兩個配置對象RouteConfigs StackNavigatorConfig ,但是這里需要注意,第二個參數StackNavigatorConfig可以省略,表示不做任何導航默認配置

StackNavigatorConfig配置參數

initialRouteName :導航器組件中初始顯示頁面的路由名稱,如果不設置,則默認第一個路由頁面為初始顯示頁面

initialRouteParams:給初始路由的參數,在初始顯示的頁面中可以通過this.props.navigation.state.params來獲取

navigationOptions:路由頁面的全局配置項

paths :RouteConfigs里面路徑設置的映射

mode :頁面跳轉方式,有card和modal兩種,默認為 card

card:普通app常用的左右切換

modal:只針對iOS平臺,類似于iOS中的模態跳轉,上下切換

headerMode :頁面跳轉時,頭部的動畫模式,有 float 、 screen 、 none 三種

float:漸變,類似iOS的原生效果,無透明,默認方式

screen:標題與屏幕一起淡入淡出,如微信QQ的一樣

none:沒有動畫

cardStyle :為各個頁面設置統一的樣式,比如背景色,字體大小等

transitionConfig :配置頁面跳轉的動畫,覆蓋默認的動畫效果

onTransitionStart :頁面跳轉動畫即將開始時調用

onTransitionEnd :頁面跳轉動畫一旦完成會馬上調用

在StackNavigatorConfig配置參數中有一個navigationOptions 屬性的配置,這個配置項可以理解為導航欄的全局配置表,下面就講解這個屬性的可配置參數

navigationOptions配置參數

title :導航欄的標題,或者Tab標題 tabBarLabel

header :自定義的頭部組件,使用該屬性后系統的頭部組件會消失,如果想在頁面中自定義,可以設置為null,這樣就不會出現頁面中留有一個高度為64navigationBar的高度

headerTitle :頭部的標題,即頁面的標題

headerBackTitle :返回標題,默認為 title的標題

headerTruncatedBackTitle :返回標題不能顯示時(比如返回標題太長了)顯示此標題,默認為"Back"

headerRight :頭部右邊組件

headerLeft :頭部左邊組件

headerStyle :頭部組件的樣式

headerTitleStyle :頭部標題的樣式

headerBackTitleStyle :頭部返回標題的樣式

headerTintColor :頭部顏色

headerPressColorAndroid :Android 5.0 以上MD風格的波紋顏色

gesturesEnabled :否能側滑返回,iOS 默認 true , Android 默認 false

navigationOptions

// StackNavigatorConfig中的navigationOptions屬性也可以在組件內用static navigationOptions 設置(會覆蓋此處的設置)
navigationOptions: { 
        header: {  // 導航欄相關設置項
            backTitle: "返回",  // 左上角返回鍵文字
            style: {
                backgroundColor: "#fff"
            },
            titleStyle: {
                color: "green"
            }
        },
        cardStack: {
            gesturesEnabled: true
        }
    }

注意:

我們也可以在RouteConfigs 中配置 navigationOptions屬性,我們也可以在多帶帶頁面配置navigationOptions

在頁面里面采用靜態的方式配置 navigationOptions屬性,會覆蓋StackNavigator函數中RouteConfigs StackNavigatorConfig 對象中的navigationOptions屬性里面的對應屬性

navigationOptions中屬性的優先級是:頁面中靜態配置 > RouteConfigs > StackNavigatorConfig

RouteConfigs 中配置 navigationOptions

const RouteConfigs = {
  Home: {
    screen: TabBar
  },
  Home2: {
    screen: Home2,
    path:"app/Home2",
   // 此處設置了, 會覆蓋組件內的`static navigationOptions`設置. 具體參數詳見下文
    navigationOptions: {
      title: "這是在RouteConfigs中設置的title",
      headerTitleStyle: {
        fontSize: 10
      }
    }
  },
  Home3: { screen: Home3 },
  Home4: { screen: Home4 },
  Home5: {screen: Home5},
  Home6: {screen: Home6},
  Home7: {screen: Home7},
  Setting2: {screen: Setting2},
  Setting3: {screen: Setting3},
}

在具體頁面中配置 navigationOptions

import {StackNavigator, TabNavigator} from "react-navigation"

const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

export default class Main extends Component {

    // 配置頁面導航選項
    static navigationOptions = {
    title: "homeThree",
    header: (navigation, defaultHeader) => ({
      ...defaultHeader,  // 默認預設
      visible: true  // 覆蓋預設中的此項
    }),
    cardStack: {
        gesturesEnabled: false  // 是否可以右滑返回
    }
}

    // 或這樣
    static navigationOptions = {
    // title: "Two", // 固定標題
    title: (navigation, childRouter) => {  // 動態標題
        if (navigation.state.params.isSelected) {
            return `${navigation.state.params.name}選中`;
        } else {
            return `${navigation.state.params.name}沒選中`;
        }
    },
    header: ({ state, setParams, goBack }) => {
        let right;
        if (state.params.isSelected) {
            right = (
TabNavigator

API

TabNavigator(RouteConfigs, TabNavigatorConfig)

從API上看,TabNavigator 和 StackNavigator 函數用法一樣,都是接受RouteConfigs和TabNavigatorConfig這兩個參數

RouteConfigs配置參數

路由配置和StackNavigator中一樣,配置路由以及對應的 screen 頁面,navigationOptions 為對應路由頁面的配置選項

title :Tab標題,可用作headerTitle 和 tabBarLabel 回退標題

tabBarVisible :Tab的是否可見,默認為 true

tabBarIcon :Tab的icon組件,可以根據 {focused: boolean, tintColor: string} 方法來返回一個icon組件

tabBarLabel :Tab中顯示的標題字符串或者組件,也可以根據{ focused: boolean, tintColor: string } 方法返回一個組件

配置RouteConfigs

const RouteConfigs = {
  Home: {
    screen: Home,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Home",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },
  People: {
    screen: People,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "People",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },
  Chat: {
    screen: Chat,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Chat",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },
  Setting: {
    screen: Setting,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Settings",
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  }
}

TabNavigatorConfig配置參數

tabBarComponent : Tab選項卡組件,有TabBarBottom和TabBarTop兩個值,在iOS中默認為 TabBarBottom ,在Android中默認為 TabBarTop

TabBarTop:在頁面的頂部

TabBarBottom:在頁面的底部

tabBarPosition :Tab選項卡的位置,有top或bottom兩個值

top:上

bottom:下

swipeEnabled :是否可以滑動切換Tab選項卡

animationEnabled :切換界面是否需要動畫

lazy :是否懶加載頁面

initialRouteName :初始顯示的Tab對應的頁面路由名稱

order :用路由名稱數組來表示Tab選項卡的順序,默認為路由配置順序

paths : 路徑配置

backBehavior :androd點擊返回鍵時的處理,有initialRoute 和 none 兩個值

initailRoute:返回初始界面

none:退出

tabBarOptions :Tab配置屬性,用在TabBarTop和TabBarBottom時有些屬性不一致

用在TabBarTop時對應的屬性:

activeTintColor:選中的文字顏色

inactiveTintColor:未選中的文字顏色

showIcon:是否顯示圖標,默認顯示

showLabel:是否顯示標簽,默認顯示

upperCaseLabel:是否使用大寫字母,默認使用

pressColor:android 5.0以上的MD風格波紋顏色

pressOpacity:android 5.0以下或者iOS按下的透明度

scrollEnabled:是否可以滾動

tabStyle:單個Tab的樣式

indicatorStyle:指示器的樣式

labelStyle:標簽的樣式

iconStyle:icon的樣式

style:整個TabBar的樣式

用在TabBarBottom時對應的屬性:

activeTintColor:選中Tab的文字顏色

inactiveTintColor:未選中Tab的的文字顏色

activeBackgroundColor:選中Tab的背景顏色

inactiveBackgroundColor:未選中Tab的背景顏色

showLabel:是否顯示標題,默認顯示

style:整個TabBar的樣式

labelStyle:標簽的樣式

tabStyle:單個Tab的樣式

使用TabBarTop代碼示例

import React, {Component} from "react";
import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
export default class MainComponent extends Component {
    render() {
        return (
            
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: "首頁",
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: "附近",
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: "我的",
        },
    }
};
const TabNavigatorConfigs = {
    initialRouteName: "Home",
    tabBarComponent: TabBarTop,
    tabBarPosition: "top",
    lazy: true,
    tabBarOptions: {}
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
    Tab: {
        screen: Tab,
    }
};
const StackNavigatorConfigs = {
    initialRouteName: "Tab",
    navigationOptions: {
        title: "標題",
        headerStyle: {backgroundColor: "#5da8ff"},
        headerTitleStyle: {color: "#333333"},
    }
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

使用TabBarBottom代碼示例

import React, {Component} from "react";
import {StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
import TabBarItem from "./index18/TabBarItem";
export default class MainComponent extends Component {
    render() {
        return (
            
        );
    }
}

const TabRouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            tabBarLabel: "首頁",
            tabBarIcon: ({focused, tintColor}) => (
                
            ),
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            tabBarLabel: "附近",
            tabBarIcon: ({focused, tintColor}) => (
                
            ),
        },
    }
    ,
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            tabBarLabel: "我的",
            tabBarIcon: ({focused, tintColor}) => (
                
            ),
        },
    }
};
const TabNavigatorConfigs = {
    initialRouteName: "Home",
    tabBarComponent: TabBarBottom,
    tabBarPosition: "bottom",
    lazy: true,
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
    Tab: {
        screen: Tab,
    }
};
const StackNavigatorConfigs = {
    initialRouteName: "Tab",
    navigationOptions: {
        title: "標題",
        headerStyle: {backgroundColor: "#5da8ff"},
        headerTitleStyle: {color: "#333333"},
    }
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
DrawerNavigator

API

DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)

DrawerNavigator StackNavigator TabNavigator 函數的使用方式一樣,參數配置也類似

路由配置和StackNavigator中一樣,配置路由以及對應的 screen 頁面,navigationOptions 為對應路由頁面的配置選項

RouteConfigs參數配置

title :抽屜標題,和headerTitle 、 drawerLabel一樣

drawerLabel :標簽字符串,或者自定義組件,可以根據{ focused: boolean, tintColor: string } 函數來返回一個自定義組件作為標簽

drawerIcon :抽屜icon,可以根據 { focused: boolean, tintColor: string } 函數來返回一個自定義組件作為icon

DrawerNavigatorConfig參數配置

drawerWidth :抽屜寬度,可以使用Dimensions獲取屏幕的寬度動態計算

drawerPosition :抽屜位置,可以是 left 或者 right

contentComponent :抽屜內容組件,可以自定義側滑抽屜中的所有內容,默認為 DrawerItems

contentOptions :用來配置抽屜內容的屬性。當用來配置 DrawerItems 是配置屬性選項

items:抽屜欄目的路由名稱數組,可以被修改

activeItemKey:當前選中頁面的key id

activeTintColor:選中條目狀態的文字顏色

activeBackgroundColor:選中條目的背景色

inactiveTintColor:未選中條目狀態的文字顏色

inactiveBackgroundColor:未選中條目的背景色

onItemPress(route) :條目按下時會調用此方法

style:抽屜內容的樣式

labelStyle:抽屜的條目標題/標簽樣式

initialRouteName :初始化展示的頁面路由名稱

order :抽屜導航欄目順序,用路由名稱數組表示

paths :路徑

backBehavior :androd點擊返回鍵時的處理,有initialRoute和none兩個值

initailRoute:返回初始界面

none :退出

示例代碼

import React, {Component} from "react";
import {DrawerNavigator, StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
import TabBarItem from "./index18/TabBarItem";

const RouteConfigs = {
    Home: {
        screen: HomeScreen,
        navigationOptions: ({navigation}) => ({
            drawerLabel : "首頁",
            drawerIcon : ({focused, tintColor}) => (
                
            ),
        }),
    },
    NearBy: {
        screen: NearByScreen,
        navigationOptions: {
            drawerLabel : "附近",
            drawerIcon : ({focused, tintColor}) => (
                
            ),
        },
    },
    Mine: {
        screen: MineScreen,
        navigationOptions: {
            drawerLabel : "我的",
            drawerIcon : ({focused, tintColor}) => (
                
            ),
        },
    }
};

const DrawerNavigatorConfigs = {
    initialRouteName: "Home",
    tabBarComponent: TabBarBottom,
    tabBarPosition: "bottom",
    lazy: true,
    tabBarOptions: {}
};

const Drawer = DrawerNavigator(RouteConfigs, DrawerNavigatorConfigs)

const StackRouteConfigs = {
    Drawer: {
        screen: Drawer,
    }
};

const StackNavigatorConfigs = {
    initialRouteName: "Drawer",
    navigationOptions: {
        title: "標題",
        headerStyle: {backgroundColor: "#5da8ff"},
        headerTitleStyle: {color: "#333333"},
    }
}

const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs)

export default class Main extends Component {
    render() {
        return (
            
        )
    }
}
navigation

在StackNavigator中注冊過的組件都有navigation這個屬性,navigation有5個主要參數

navigate

state

setParams

goBack

dispatch

我們平時使用react-navigation作為導航組件來開發時,經常使用到的也就是這5個屬性的功能

navigate

導航到下一個頁面

導航到下一個頁面并傳遞參數

navigation中的navigate函數可以接受三個參數

routeName :注冊過的目標路由名稱,也就是準備跳轉到的頁面路由地址(例如上面的Home3)

params :跳轉到下一個頁面,傳遞的參數(例如上面的id)

action :下文有講到

state

state屬性包含有傳遞過來的三個參數 params、key 、routeName

routeName :注冊過的目標路由名稱

key :路由身份標識

params :跳轉時傳遞的參數

獲取state中的參數:this.props.navigation.state.params.id 這樣就能拿到上一個頁面傳遞的參數:id

setParams

this.props.navigation.setParams(): 該方法允許界面更改router中的參數,可以用來動態的更改導航欄的內容。比如可以用來更新頭部的按鈕或者標題等

使用場景:重寫導航按鈕的返回按鈕,自定義返回事件

export default class Home5 extends Component {

  static navigationOptions = ({navigation, screenProps}) => ({
      title: "Home5",
      headerLeft: (
        

goBack

退出當前頁面,返回到上一個頁面,可以不傳參數,也可以傳參數,還可以傳 null

this.props.navigation.goBack(); // 回退到上一個頁面

this.props.navigation.goBack(null); // 回退到任意一個頁面

this.props.navigation.goBack("Home"); // 回退到Home頁面

dispatch

this.props.navigation.dispatch: 可以dispatch一些action,主要支持的action有一下幾種

Navigate

import { NavigationActions } from "react-navigation"

  const navigationAction = NavigationActions.navigate({
    routeName: "Profile",
    params: {},

    // navigate can have a nested navigate action that will be run inside the child router
    action: NavigationActions.navigate({ routeName: "SubProfileRoute"})
  })
  this.props.navigation.dispatch(navigationAction)

Reset

Reset方法會清除原來的路由記錄,添加上新設置的路由信息, 可以指定多個action,index是指定默認顯示的那個路由頁面, 注意不要越界了

import { NavigationActions } from "react-navigation"

  const resetAction = NavigationActions.reset({
    index: 0,
    actions: [
      NavigationActions.navigate({ routeName: "Profile"}),
      NavigationActions.navigate({ routeName: "Two"})
    ]
  })
  this.props.navigation.dispatch(resetAction)

SetParams

為指定的router更新參數,該參數必須是已經存在于router的param中

import { NavigationActions } from "react-navigation"

  const setParamsAction = NavigationActions.setParams({
    params: {}, // these are the new params that will be merged into the existing route params
    // The key of the route that should get the new params
    key: "screen-123",
  })
  this.props.navigation.dispatch(setParamsAction)

Back

NavigationActions.back()

Init

const initialState = Navigator.router.getStateForAction(NavigationActions.init());

export default (state = initialState, actions) => {
    const nextState = Navigator.router.getStateForAction(actions, state);
    return nextState || state;
}

注意: 如果你的項目中使用了與Redux框架結合,這里的dispatch就可以派發任何你想dispatch的Action了

使用場景:Counter 計數器

class Counter extends Component {

  static navigationOptions = () => ({
    title: "Counter加減計數器"
  })

  render() {
    const {dispatch} = this.props.navigation
    return (
      
        Counter
        {this.props.counterValue}
        
常用功能:頁面跳轉、頁面傳值、參數回調

頁面跳轉與傳值

          

在下一界面接收參數,通過this.props.navigation.state.params接收參數

export default class Home3 extends Component {

  render() {
    const {navigate} = this.props.navigation
    return (
      
        Home3
        {`Home界面傳遞的參數為:${this.props.navigation.state.params.id}`}
        

回調傳參

當前界面進行跳轉,并傳遞參數

          

下一界面在返回之前執行函數回調傳參給上一個頁面

    const {state, goBack} = this.props.navigation

        
DeepLink

其他app或瀏覽器使用url打開次app并進入指定頁面,類似于iOS中的URL導航一樣。如瀏覽器輸入url OneM://home/home2直接進入home2頁面

iOS平臺需要額外配置

在info.plist文件中設置Schemes,示例中的Schemes為:OneM

在AppDelegate添加代理函數

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}

在js中配置

js組件在注冊路由時設置唯一的路徑path, 例如Home2: { screen: Home2, path:"home/Home2"}

在手機瀏覽器訪問OneM://home/Home2, 彈窗選擇打開, 就可以打開OneM app并進到Home2頁面了

開發中遇到的問題及注意事項

默認DrawerView不可滾動。要實現可滾動視圖,必須使用contentComponent自定義容器

{  
  drawerWidth:200, 
  contentComponent:props =>     
}

可以覆蓋導航使用的默認組件,使用DrawerItems自定義導航組件

import {DrawerItems} from "react-navigation";  

const CustomDrawerContentComponent = (props) => (  
    
      
      
)

嵌套抽屜導航 如果嵌套DrawerNavigation,抽屜將顯示在父導航下方

適配頂部導航欄標題

測試中發現,在iphone上標題欄的標題為居中狀態,而在Android上則是居左對齊。所以需要我們修改源碼,進行適配
【node_modules – react-navigation – src – views – Header.js】的326行代碼處,修改為如下:

title: {  
   bottom: 0,  
   left: TITLE_OFFSET,  
   right: TITLE_OFFSET,  
   top: 0,  
   position: "absolute",  
   alignItems: "center",  
 } 

上面方法通過修改源碼的方式其實略有弊端,畢竟擴展性不好。還有另外一種方式就是,在navigationOptions中設置headerTitleStyle的alignSelf為 ’ center ‘即可解決

去除返回鍵文字顯示

【node_modules – react-navigation – src – views – HeaderBackButton.js】的91行代碼處,修改為如下即可

{
   Platform.OS === "ios" &&  
     title &&  
       
       {backButtonTitle}  
     
  } 

將上述代碼刪除即可

動態設置頭部按鈕事件

當我們在頭部設置左右按鈕時,肯定避免不了要設置按鈕的單擊事件,但是此時會有一個問題,navigationOptions是被修飾為static類型的,所以我們在按鈕的onPress的方法中不能直接通過this來調用Component中的方法。如何解決呢?在官方文檔中,作者給出利用設置params的思想來動態設置頭部標題。那么我們可以利用這種方式,將單擊回調函數以參數的方式傳遞到params,然后在navigationOption中利用navigation來取出設置到onPress即可:

export default class Home5 extends Component {

  static navigationOptions = ({navigation, screenProps}) => ({
      title: "Home5",
      headerRight: (
        

結合BackHandler處理返回和點擊返回鍵兩次退出App效果

點擊返回鍵兩次退出App效果的需求屢見不鮮。相信很多人在react-navigation下實現該功能都遇到了很多問題,例如,其他界面不能返回。也就是手機本身返回事件在react-navigation之前攔截了。如何結合react-natigation實現呢?和大家分享兩種實現方式:

在注冊StackNavigator的界面中,注冊BackHandler

componentWillMount(){  
    BackHandler.addEventListener("hardwareBackPress", this._onBackAndroid );  
}  


componentUnWillMount(){  
    BackHandler.addEventListener("hardwareBackPress", this._onBackAndroid);  
}  

_onBackAndroid=()=>{  
    let now = new Date().getTime();  
    if(now - lastBackPressed < 2500) {  
        return false;  
    }  
    lastBackPressed = now;  
    ToastAndroid.show("再點擊一次退出應用",ToastAndroid.SHORT);  
    return true;  
} 

監聽react-navigation的Router

/** 
 * 處理安卓返回鍵 
 */  
const defaultStateAction = AppNavigator.router.getStateForAction;  
AppNavigator.router.getStateForAction = (action,state) => {  
    if(state && action.type === NavigationActions.BACK && state.routes.length === 1) {  
        if (lastBackPressed + 2000 < Date.now()) {  
            ToastAndroid.show(Constant.hint_exit,ToastAndroid.SHORT);  
            lastBackPressed = Date.now();  
            const routes = [...state.routes];  
            return {  
                ...state,  
                ...state.routes,  
                index: routes.length - 1,  
            };  
        }  
    }  
    return defaultStateAction(action,state);  
}

實現Android中界面跳轉左右切換動畫

react-navigation在android中默認的界面切換動畫是上下。如何實現左右切換呢?很簡單的配置即可:

import CardStackStyleInterpolator from "react-navigation/src/views/CardStackStyleInterpolator";  

然后在StackNavigator的配置下添加如下代碼:

transitionConfig:()=>({  
    screenInterpolator: CardStackStyleInterpolator.forHorizontal,  
}) 

解決快速點擊多次跳轉

當我們快速點擊跳轉時,會開啟多個重復的界面,如何解決呢。其實在官方Git中也有提示,解決這個問題需要修改react-navigation源碼:
找到scr文件夾中的addNavigationHelpers.js文件,替換為如下文本即可:

export default function(navigation: NavigationProp) {  
  // 添加點擊判斷  
  let debounce = true;  
  return {  
      ...navigation,  
      goBack: (key?: ?string): boolean =>  
          navigation.dispatch(  
              NavigationActions.back({  
                  key: key === undefined ? navigation.state.key : key,  
              }),  
          ),  
      navigate: (routeName: string,  
                 params?: NavigationParams,  
                 action?: NavigationAction,): boolean => {  
          if (debounce) {  
              debounce = false;  
              navigation.dispatch(  
                  NavigationActions.navigate({  
                      routeName,  
                      params,  
                      action,  
                  }),  
              );  
              setTimeout(  
                  () => {  
                      debounce = true;  
                  },  
              500,  
              );  
              return true;  
          }  
          return false;  
      },  
    /** 
     * For updating current route params. For example the nav bar title and 
     * buttons are based on the route params. 
     * This means `setParams` can be used to update nav bar for example. 
     */  
    setParams: (params: NavigationParams): boolean =>  
      navigation.dispatch(  
        NavigationActions.setParams({  
          params,  
          key: navigation.state.key,  
        }),  
      ),  
  }
}
待補充問題

hook tabBar上點擊事件

Android物理返回鍵處理

navigator與tabBar嵌套

tabBar上添加badge

pop多層頁面

pop到指定頁面

navigator與抽屜嵌套使用

導航title 在Android 平臺上不居中顯示

雙擊物理鍵,退出app

懶加載tabbar上數據

針對上面的待補充問題,下面來逐一解答

hook tabBar上點擊事件

有時我們點擊tabBar上的tab來切換頁面,但是在切換頁面之前我們想先做一些邏輯處理,然后在切換到tab頁面,這時我們就需要先hook到這個tab的點擊事件,下面代碼塊就是告訴你如何hook到tab的點擊事件,處理完事件在打開tab頁面,這個使用具體使用方式在示例Demo中都有實際使用,不清楚的同學們直接去運行示例項目了解即可
Chat: {
    screen: Chat,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "Chat",
      tabBarOnPress: () => {
        Alert.alert(
            "注意!",
            "這里做了hook tabBar的點擊事件操作,我們可以hook到這個點擊事件,處理我們想要處理的業務后再打開 Chat這個頁面",
            [
              {text: "打開tab頁面", onPress: () => navigation.navigate("Chat")},
              {text: "Cancel", onPress: () => console.log("Cancel Pressed"), style: "cancel"},
            ],
            { cancelable: false }
        )
      },
      tabBarIcon: ({ focused, tintColor }) => (
        
      )
    }),
  },

Android物理返回鍵處理(待更新)

navigator與tabBar嵌套

navigator與tabBar嵌套 具體的結合使用方式示例Demo中有給出具體示例,這個同學們直接運行示例Demo查看即可

tabBar上添加badge

之前有不少同學問我,怎么給一個tabBar設置badge,前段時間由于太忙,一直沒有去處理這個問題,后面去實現了下自定義badge,感覺還是挺簡單的,因為navigation的tabBarItem本來就是支持自定義的,既然能夠自定義,那實現badge自然也是可行的了,下面就是具體實現代碼塊
People: {
    screen: People,
    navigationOptions: ({ navigation }) => ({
      tabBarLabel: "People",
      tabBarIcon: ({ focused, tintColor }) => (
          
            
            
              10
            
          
      )
    }),
  },

pop多層頁面

有時候我們在開發的時候,難免會遇到在點擊返回按鈕的時候,想直接返回到指定的某一個頁面,而不是返回上一級頁面,這時我們就需要對goback()函數做些處理了,具體的代碼實現如下
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

const defaultStateAction = Navigator.router.getStateForAction;

Navigator.router.getStateForAction = (action, state) => {
  if (state && action.key && action.type === "Navigation/BACK") {
    const desiredRoute = state.routes.find((route) => route.routeName === action.key)
    if (desiredRoute) {
      const index = state.routes.indexOf(desiredRoute)
      const finalState = {
        ...state,
        routes: state.routes.slice(0, index + 1),
        index: index,
      };
      return finalState
    } else {
      if (state.routes.length > action.key) {
        const stacksLength = state.routes.length - action.key
        const stacks = state.routes.slice(0, stacksLength)
        const finalState = {
          ...state,
          routes: stacks,
          index: stacksLength - 1,
        };
        return finalState
      }
    }
  }
  return defaultStateAction(action, state)
}

pop到指定頁面

其實goback()函數,是很容易的就可以做到返回到指定頁面,和返回指定層級的頁面的,并不像網上其他的文章說的需要改源碼啊,或者是需要結合redux才能實現啊,并不是這樣的,只需要我們簡單的維護下導航的路由棧即可解決問題,這個其實和原生iOS中處理導航的棧管理是一個道理
const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig)

const defaultStateAction = Navigator.router.getStateForAction;

Navigator.router.getStateForAction = (action, state) => {
  if (state && action.key && action.type === "Navigation/BACK") {
    const desiredRoute = state.routes.find((route) => route.routeName === action.key)
    if (desiredRoute) {
      const index = state.routes.indexOf(desiredRoute)
      const finalState = {
        ...state,
        routes: state.routes.slice(0, index + 1),
        index: index,
      };
      return finalState
    } else {
      if (state.routes.length > action.key) {
        const stacksLength = state.routes.length - action.key
        const stacks = state.routes.slice(0, stacksLength)
        const finalState = {
          ...state,
          routes: stacks,
          index: stacksLength - 1,
        };
        return finalState
      }
    }
  }
  return defaultStateAction(action, state)
}

navigator與抽屜嵌套使用

navigator與抽屜嵌套使用的方式,示例Demo中已經有具體實現了,這個比較簡單,就不做詳細解答了

導航title 在Android 平臺上不居中顯示

簡書上面的開發中遇到的問題及注意事項中有講解決辦法,不過作者還是建議大家將導航欄封裝成一個組件,使用自定義的組件靈活性更高

雙擊物理鍵,退出app(待更新)

懶加載tabbar上數據

這個懶加載Tab,這個也沒有什么好解答的,官方已經給我提供了設置屬性,我們只需要設置個屬性即可,具體代碼如下
const TabNavigatorConfigs = {
  initialRouteName: "Home",
  lazy: true,
  tabBarOptions: {
    activeTintColor: Platform.OS === "ios" ? "#e91e63" : "#fff",
  }
}
總結
react-navigation導航組件的API相對較多,如果小伙伴們看完講解還是不清楚如何使用,建議直接運行Demo項目,邊調試邊理解。

針對之前很多同學反映出關于react-navigation 使用上遇到的一些問題,上面基本上都逐一解答了,并且都在示例Demo實戰的測試過是可行方案,后期還有其他的小伙伴遇到使用上的問題,歡迎進群討論,或者是給我簡書留言,謝謝大家的支持。

作者提供的Demo地址

https://github.com/guangqiang-liu/react-navigation-demo

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97454.html

相關文章

  • react-navigation使用小記(2) 自定義header菜單項

    摘要:使用實現菜單組件。日常廢話上一篇文章講了如何用創建各種自定義頭部。這篇水文講一下如何實現右部的菜單項。怎么實現自定義頭部右側很簡單,配置的選項,傳入我們的自定義組件即可。在配置時,通過一個閉包保存菜單項的狀態。提一點菜單項的是。 使用react-navigation實現headerRight菜單組件。 日常廢話 上一篇文章講了如何用react-navigation創建各種自定義頭部(h...

    ixlei 評論0 收藏0
  • react-native, react-navigation, redux 學習筆記

    摘要:的使用用戶發出函數算出新的重新渲染三大原則單一數據源,利用的形式向下傳播數據流決定只讀,通過修改通過純函數來修改組件狀態,是描述動作的純函數連接和基于全局的,選擇我們要注入的不同的組件分開把注入,讀取方法三劍客先確定一下初始狀 redux的使用 react-native, react, react-redux, react-navigaition, redux-thunk, redu...

    妤鋒シ 評論0 收藏0
  • #react-navigation# 學習重點記錄

    摘要:在上,掛鉤到硬件的返回按鈕,并在用戶按下返回按鈕時觸發方法,因此它的行為與用戶期望的相同。傳遞參數給路由有個知識點需要將參數包裝成一個對象,作為方法的第二個參數傳遞給路由。默認情況下按照平臺慣例設置,所以在上標題居中,在上左對齊。 push 和 navigate的區別 push: 每次調用 push 時, 我們會向導航堆棧中添加新路由。 navigate: 當你調用 navigat...

    fyber 評論0 收藏0

發表評論

0條評論

stonezhu

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<