react-navigation使用技巧

react-navigation簡介

react-navigation是致力于解決導(dǎo)航卡頓,數(shù)據(jù)傳遞,Tabbar和navigator布局,支持redux,具有原生般的性能體驗(yàn)效果。可能會(huì)成為未來React Native導(dǎo)航組件的主流軍。Fb推薦使用庫,并且在React Native當(dāng)前最新版本0.44中將Navigator刪除。

屬性

react-navigation分為三個(gè)部分。
StackNavigator類似頂部導(dǎo)航條,用來跳轉(zhuǎn)頁面和傳遞參數(shù)。
TabNavigator類似底部標(biāo)簽欄,用來在同一屏幕下切換不同界面
DrawerNavigator抽屜,類似從App左側(cè)滑出一個(gè)頁面,在這里不做講解。

screenProps

screenProps:react-navigation自帶的一個(gè)屬性,屬于navigationOptions的一個(gè)屬性,可以全局控制navigationOptions中的某些值,比如說你想做換膚功能,修改這個(gè)屬性絕對是最簡單的方式。

// 假設(shè)App就是項(xiàng)目中的入口文件,如果還不知道,可以看下Demo,在這里我將主題色通過screenProps屬性修改成'red'
<App screenProps={{themeColor:'red'}}>

// 在頁面中就可以通過screenProps來直接改變了,這個(gè)在Demo
中的Test2里面

static navigationOptions = ({navigation,screenProps}) => ({
        // 這里面的屬性和App.js的navigationOptions是一樣的。
                headerStyle:{backgroundColor:screenProps?
                screenProps.themeColor:
                '#4ECBFC'},


    )
})

StackNavigator 基礎(chǔ)用法/屬性介紹

const MyApp = StackNavigator({
    // 對應(yīng)界面名稱
    MyTab: {
        screen: MyTab,
    },
    Detail: {
        screen: Detail,
        navigationOptions:{
            headerTitle:'詳情',
            headerBackTitle:null,
        }
    },
}, {
    headerMode: 'screen',
});

導(dǎo)航配置

screen:對應(yīng)界面名稱,需要填入import之后的頁面。

navigationOptions:配置StackNavigator的一些屬性。

  • title:標(biāo)題,如果設(shè)置了這個(gè)導(dǎo)航欄和標(biāo)簽欄的title就會(huì)變成一樣的,所以不推薦使用這個(gè)方法。
  • header:可以設(shè)置一些導(dǎo)航的屬性,當(dāng)然如果想隱藏頂部導(dǎo)航條只要將這個(gè)屬性設(shè)置為null就可以了。
  • headerTitle:設(shè)置導(dǎo)航欄標(biāo)題,推薦用這個(gè)方法。
  • headerBackTitle:設(shè)置跳轉(zhuǎn)頁面左側(cè)返回箭頭后面的文字,默認(rèn)是上一個(gè)頁面的標(biāo)題??梢宰远x,也可以設(shè)置為null
  • headerTruncatedBackTitle:設(shè)置當(dāng)上個(gè)頁面標(biāo)題不符合返回箭頭后的文字時(shí),默認(rèn)改成"返回"。(上個(gè)頁面的標(biāo)題過長,導(dǎo)致顯示不下,所以改成了短一些的。)
  • headerRight:設(shè)置導(dǎo)航條右側(cè)。可以是按鈕或者其他。
  • headerLeft:設(shè)置導(dǎo)航條左側(cè)??梢允前粹o或者其他。
  • headerStyle:設(shè)置導(dǎo)航條的樣式。背景色,寬高等。如果想去掉安卓導(dǎo)航條底部陰影可以添加elevation: 0,iOS下用shadowOpacity: 0。
  • headerTitleStyle:設(shè)置導(dǎo)航條文字樣式。安卓上如果要設(shè)置文字居中,只要添加alignSelf:'center'就可以了。在安卓上會(huì)遇到,如果左邊有返回箭頭導(dǎo)致文字還是沒有居中的問題,最簡單的解決思路就是在右邊也放置一個(gè)空的按鈕。
  • headerBackTitleStyle:設(shè)置導(dǎo)航條返回文字樣式。
  • headerTintColor:設(shè)置導(dǎo)航欄文字顏色??偢杏X和上面重疊了。
  • headerPressColorAndroid:安卓獨(dú)有的設(shè)置顏色紋理,需要安卓版本大于5.0
  • gesturesEnabled:是否支持滑動(dòng)返回手勢,iOS默認(rèn)支持,安卓默認(rèn)關(guān)閉
  • gestureResponseDistance:對象覆蓋觸摸從屏幕邊緣開始的距離,以識(shí)別手勢。 它需要以下屬性:
  • horizontal - number - 水平方向的距離 默認(rèn)為25。
  • vertical - number - 垂直方向的距離 默認(rèn)為135。
// 設(shè)置滑動(dòng)返回的距離
gestureResponseDistance:{horizontal:300},

導(dǎo)航視覺效果

  • mode:定義跳轉(zhuǎn)風(fēng)格。

  • card:使用iOS和安卓默認(rèn)的風(fēng)格。

  • modal:iOS獨(dú)有的使屏幕從底部畫出。類似iOS的present效果

  • headerMode:邊緣滑動(dòng)返回上級頁面時(shí)動(dòng)畫效果。

  • float:iOS默認(rèn)的效果,可以看到一個(gè)明顯的過渡動(dòng)畫。

  • screen:滑動(dòng)過程中,整個(gè)頁面都會(huì)返回。

  • none:沒有動(dòng)畫。

  • cardStyle:自定義設(shè)置跳轉(zhuǎn)效果。

  • transitionConfig: 自定義設(shè)置滑動(dòng)返回的配置。

  • onTransitionStart:當(dāng)轉(zhuǎn)換動(dòng)畫即將開始時(shí)被調(diào)用的功能。

  • onTransitionEnd:當(dāng)轉(zhuǎn)換動(dòng)畫完成,將被調(diào)用的功能。

  • path:路由中設(shè)置的路徑的覆蓋映射配置。

  • initialRouteName:設(shè)置默認(rèn)的頁面組件,必須是上面已注冊的頁面組件。

  • initialRouteParams:初始路由的參數(shù)。

  • path:path屬性適用于其他app或?yàn)g覽器使用url打開本app并進(jìn)入指定頁面。path屬性用于聲明一個(gè)界面路徑,例如:【/pages/Home】。此時(shí)我們可以在手機(jī)瀏覽器中輸入:app名稱://pages/Home來啟動(dòng)該App,并進(jìn)入Home界面。

TabNavigator 基礎(chǔ)用法/屬性介紹

const MyTab = TabNavigator({
    ShiTu: {
        screen: ShiTu,
        navigationOptions:{
            tabBarLabel: '內(nèi)容',
            tabBarIcon: ({tintColor}) => (
                <Image
                    source={{uri : '內(nèi)容'}}
                    style={[tabBarIcon, {tintColor: tintColor}]}
                />
            ),
        },
    }, {
    tabBarPosition: 'bottom',
    swipeEnabled:false,
    animationEnabled:false,
    tabBarOptions: {
        style: {
            height:49
        },
        activeBackgroundColor:'white',
        activeTintColor:'#4ECBFC',
        inactiveBackgroundColor:'white',
        inactiveTintColor:'#aaa',
        showLabel:false,
    }
});

屏幕導(dǎo)航配置

  • screen:和導(dǎo)航的功能是一樣的,對應(yīng)界面名稱,可以在其他頁面通過這個(gè)screen傳值和跳轉(zhuǎn)。

  • navigationOptions:配置TabNavigator的一些屬性

  • title:標(biāo)題,會(huì)同時(shí)設(shè)置導(dǎo)航條和標(biāo)簽欄的title,還是不推薦這種方式。

  • tabBarVisible:是否隱藏標(biāo)簽欄。默認(rèn)不隱藏(true)

  • tabBarIcon:設(shè)置標(biāo)簽欄的圖標(biāo)。需要給每個(gè)都設(shè)置。

  • tabBarLabel:設(shè)置標(biāo)簽欄的title。推薦這個(gè)方式。

  • tabBarOnPress:設(shè)置tabBar的點(diǎn)擊事件,內(nèi)部提供了兩個(gè)屬性,一個(gè)方法(obj)。

  • beta13新添加的方法,使用方式有些奇葩,如果想要使用,請參照下面的代碼

tabBarOnPress:(obj)=>{
            console.log(obj);

            obj.jumpToIndex(obj.scene.index)
        },

標(biāo)簽欄配置

  • tabBarPosition:設(shè)置tabbar的位置,iOS默認(rèn)在底部,安卓默認(rèn)在頂部。(屬性值:'top','bottom')

  • swipeEnabled:是否允許在標(biāo)簽之間進(jìn)行滑動(dòng)。

  • animationEnabled:是否在更改標(biāo)簽時(shí)顯示動(dòng)畫。

  • lazy:是否根據(jù)需要懶惰呈現(xiàn)標(biāo)簽,而不是提前制作,意思是在app打開的時(shí)候?qū)⒌撞繕?biāo)簽欄全部加載,默認(rèn)false,推薦改成true哦。

  • initialRouteName: 設(shè)置默認(rèn)的頁面組件

  • backBehavior:按 back 鍵是否跳轉(zhuǎn)到第一個(gè)Tab(首頁), none 為不跳轉(zhuǎn)

  • tabBarOptions:配置標(biāo)簽欄的一些屬性

iOS屬性

  • activeTintColor:label和icon的前景色 活躍狀態(tài)下(選中)。
  • activeBackgroundColor:label和icon的背景色 活躍狀態(tài)下(選中) 。
  • inactiveTintColor:label和icon的前景色 不活躍狀態(tài)下(未選中)。
  • inactiveBackgroundColor:label和icon的背景色 不活躍狀態(tài)下(未選中)。
  • showLabel:是否顯示label,默認(rèn)開啟。
  • style:tabbar的樣式。
  • labelStyle:label的樣式。

安卓屬性

  • activeTintColor:label和icon的前景色 活躍狀態(tài)下(選中) 。
  • inactiveTintColor:label和icon的前景色 不活躍狀態(tài)下(未選中)。
  • showIcon:是否顯示圖標(biāo),默認(rèn)關(guān)閉。
  • showLabel:是否顯示label,默認(rèn)開啟。
  • style:tabbar的樣式。
  • labelStyle:label的樣式。
  • upperCaseLabel:是否使標(biāo)簽大寫,默認(rèn)為true。
  • pressColor:material漣漪效果的顏色(安卓版本需要大于5.0)。
  • pressOpacity:按壓標(biāo)簽的透明度變化(安卓版本需要小于5.0)。
  • scrollEnabled:是否啟用可滾動(dòng)選項(xiàng)卡。
  • tabStyle:tab的樣式。
  • indicatorStyle:標(biāo)簽指示器的樣式對象(選項(xiàng)卡底部的行)。安卓底部會(huì)多出一條線,可以將height設(shè)置為0來暫時(shí)解決這個(gè)問題。
  • iconStyle:圖標(biāo)的樣式。
    ps:安卓上的tabbar文字會(huì)下移, 是因?yàn)榘沧勘萯OS多了一個(gè)屬性,就是iconStyle,通過設(shè)置labelStyle和iconStyle兩個(gè)樣式,外加style的高度,來使效果更佳合理.

跳轉(zhuǎn)

navigate('Detail',{
                   title:'圖片詳情',
                   url:item.url,
                   });

Detail:在StackNavigator中注冊的頁面,需要一一對應(yīng),才能跳轉(zhuǎn)到相應(yīng)的頁面
title:在跳轉(zhuǎn)的頁面可以通過this.props.navigation.state.params.title獲取到這個(gè)參數(shù)。當(dāng)然這個(gè)參數(shù)可以隨便填寫,都可以通過this.props.navigation.state.params.xxx獲取。

回調(diào)傳參

navigate('Detail',{
                   // 跳轉(zhuǎn)的時(shí)候攜帶一個(gè)參數(shù)去下個(gè)頁面
                   callback: (data)=>{
                         console.log(data); // 打印值為:'回調(diào)參數(shù)'
                     }
                   });
const {navigate,goBack,state} = this.props.navigation;
// 在第二個(gè)頁面,在goBack之前,將上個(gè)頁面的方法取到,并回傳參數(shù),這樣回傳的參數(shù)會(huì)重走render方法
state.params.callback('回調(diào)參數(shù)');
goBack();

自定義

項(xiàng)目中基本是沒可能用自帶的那個(gè)導(dǎo)航條的,自帶導(dǎo)航條左側(cè)的按鈕永遠(yuǎn)是藍(lán)色的,如果我們需要更改按鈕顏色,就需要用到自定義的功能了。

const StackOptions = ({navigation}) => {
    console.log(navigation);
    let {state,goBack} = navigation;
    
    // 用來判斷是否隱藏或顯示header
    const visible= state.params.isVisible;
    let header;
    if (visible === true){
        header = null;
    }
    const headerStyle = {backgroundColor:'#4ECBFC'};
    const headerTitle = state.params.title;
    const headerTitleStyle = {fontSize:FONT_SIZE(20),color:'white',fontWeight:'500'}
    const headerBackTitle = false;
    const headerLeft = (
        <Button
            isCustom={true}
            customView={
                            <Icon
                                name='ios-arrow-back'
                                size={30}
                                color='white'
                                style={{marginLeft:13}}
                            />
                        }
            onPress={()=>{goBack()}}
        />
    );
    return {headerStyle,headerTitle,headerTitleStyle,headerBackTitle,headerLeft,header}
};

然后通過下面的方法調(diào)用就可以自定制導(dǎo)航了。

const MyApp = StackNavigator({
    MyTab: {
        screen: MyTab,
    },
    Detail: {
        screen: Detail,
        navigationOptions: ({navigation}) => StackOptions({navigation})
    },
)};

在頁面中使用的時(shí)候,在跳轉(zhuǎn)頁面的時(shí)候需要傳遞title參數(shù),才能看到效果哦。

自定義tabbar

tabBarIcon除了tintColor還有另一個(gè)屬性,用來判斷選中狀態(tài)的focused。

 tabBarIcon: ({tintColor,focused}) => (
                focused
                    ?
                    <Image
                        source={{uri : '識(shí)兔'}}
                        style={tabBarIcon}
                    />
                    :
                    <Image
                        source={{uri : '干貨'}}
                        style={[tabBarIcon, {tintColor: tintColor}]}
                    />
            ),

通過判斷focused,選中狀態(tài)下使用識(shí)兔圖標(biāo),未選中狀態(tài)使用干貨圖標(biāo)。
如果想使用圖標(biāo)原來的樣子,那就將style的tintColor去掉,這樣就會(huì)顯示圖標(biāo)原本的顏色。

再封裝

export const TabOptions = (tabBarTitle,normalImage,selectedImage,navTitle) => {
    // console.log(navigation);
    const tabBarLabel = tabBarTitle;
    console.log(navTitle);
    const tabBarIcon = (({tintColor,focused})=> {
        return(
            focused
                ?
                <Image
                    source={{uri : normalImage}}
                    style={[TabBarIcon, {tintColor: tintColor}]}
                />
                :
                <Image
                    source={{uri : selectedImage}}
                    style={[TabBarIcon, {tintColor: tintColor}]}
                />
        )
    });
    const headerTitle = navTitle;
    const headerTitleStyle = {fontSize:FONT_SIZE(20),color:'white'};
    // header的style
    const headerStyle = {backgroundColor:'#4ECBFC'};
    return {tabBarLabel,tabBarIcon,headerTitle,headerTitleStyle,headerStyle};
};

在static中使用this方法

我之前文章中是將navaigationOptions的方法寫在了app.js中,沒有在頁面中通過static navaigationOptions來初始化頁面,這段時(shí)間剛好有人問,所以在這里就寫一下該怎么弄。

首先需要在componentDidMount(){}中動(dòng)態(tài)的添加點(diǎn)擊事件
屬性給params

componentDidMount(){

    this.props.navigation.setParams({
        title:'自定義Header',
        navigatePress:this.navigatePress
    })
}
navigatePress = () => {
    alert('點(diǎn)擊headerRight');
    console.log(this.props.navigation);
}

接下來就可以通過params方法來獲取點(diǎn)擊事件了

static navigationOptions = ({ navigation, screenProps }) => ({
        title: navigation.state.params?navigation.state.params.title:null,
        headerRight:(
            <Text onPress={navigation.state.params?navigation.state.params.navigatePress:null}>
                返回
            </Text>
        )
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容