RN-Navigation 的使用

本文內(nèi)容
1、navigation、tabbar 的分離、navigation的使用
2、傳值、回調(diào)
3、每個頁面設(shè)置 navigator
4、navigation reset方法
5、關(guān)于返回指定頁面(原)
5、關(guān)于返回指定頁面(新)

程序目錄

3D6B6EE2-5488-4648-811B-A2A7F5E06322.png

一、navigation、tabbar 的分離、navigation的使用

index.ios.js

require('./AppRoot/root');

root.js

/**
 * Created by mymac on 2017/8/18.
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View
} from 'react-native';
import {StackNavigator} from "react-navigation";

import Navigator from './natigation';

/*
 navigation 構(gòu)造函數(shù)
 */
const Navigation = StackNavigator(Navigator.AppNavigationRouterConfigs, Navigator.AppNavigationStackConfigs);


class MainComponent extends Component {

    render() {
        return (
            <Navigation 
                    onNavigationStateChange={(prevNav, nav, action)=>{
                            // 每次導(dǎo)航改變時,都會走這個方法,可以再次判斷邏輯
                            console.log('prevNav=',prevNav);
                            console.log('nav=',nav);
                            console.log('action=',action);
            />
        );
    }

}

AppRegistry.registerComponent('Navigation', () => MainComponent);

navigation.js

/**
 * Created by mymac on 2017/8/18.
 */
import {TabNavigator} from "react-navigation";

import FirstCtrl from '../controllers/firstCtrl';
import SecondCtrl from '../controllers/secondCtrl';
import ThirdCtrl from '../controllers/thirdCtrl';

import AppTab from './tabBar';

// 動畫效果
// forHorizontal:從右向左進(jìn)入
// forVertical:從下向上進(jìn)入
// forFadeFromBottomAndroid:從底部淡出
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';


/*
 title - 可以作為頭部標(biāo)題 headerTitle ,或者Tab標(biāo)題 tabBarLabel
 header - 自定義的頭部組件,使用該屬性后系統(tǒng)的頭部組件會消失
 headerTitle - 頭部的標(biāo)題,即頁面的標(biāo)題
 headerBackTitle - 返回標(biāo)題,默認(rèn)為 title
 headerTruncatedBackTitle - 返回標(biāo)題不能顯示時(比如返回標(biāo)題太長了)顯示此標(biāo)題,默認(rèn)為 “Back”
 headerRight - 頭部右邊組件
 headerLeft - 頭部左邊組件
 headerStyle - 頭部組件的樣式
 headerTitleStyle - 頭部標(biāo)題的樣式
 headerBackTitleStyle - 頭部返回標(biāo)題的樣式
 headerTintColor - 頭部顏色
 headerPressColorAndroid - Android 5.0 以上MD風(fēng)格的波紋顏色
 gesturesEnabled - 否能側(cè)滑返回, iOS 默認(rèn) true , Android 默認(rèn) false
 */

/*
 構(gòu)造函數(shù)
 */
const Tab = TabNavigator(AppTab.AppRootTabBarRouteConfigs, AppTab.AppRootTabBarNavigatorConfigs);

/* 配置路由,所有要跳轉(zhuǎn)的頁面都需要在此聲明 */

const AppNavigationRouterConfigs = {
    TabBar: {
        screen: Tab,
        navigationOptions: ({navigation}) => ({
            title: '首頁',
            headerBackTitle: '首頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題 , 類似iOS的 backBarItem
        }),
    },

    First: {
        screen: FirstCtrl,
        navigationOptions: ({navigation}) => ({
            title: '第一頁',
            headerBackTitle: '第一頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題

        }),
    },
    Second: {
        screen: SecondCtrl,
        navigationOptions: ({navigation}) => ({
            title: '第二頁',
            headerBackTitle: '第二頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題

        }),
    },
    Third: {
        screen: ThirdCtrl,
        navigationOptions: ({navigation}) => ({
            title: '第三頁',
            headerBackTitle: '第三頁', // 給下一個頁面的返回按鈕設(shè)置標(biāo)題

        }),
    }

};

/*
 initialRouteName - 導(dǎo)航器組件中初始顯示頁面的路由名稱,如果不設(shè)置,則默認(rèn)第一個路由頁面為初始顯示頁面
 initialRouteParams - 給初始路由的參數(shù),在初始顯示的頁面中可以通過 this.props.navigation.state.params 來獲取
 navigationOptions - 路由頁面的配置選項(xiàng),它會被 RouteConfigs 參數(shù)中的 navigationOptions 的對應(yīng)屬性覆蓋。
 paths - 路由中設(shè)置的路徑的覆蓋映射配置
 mode - 頁面跳轉(zhuǎn)方式,有 card 和 modal 兩種,默認(rèn)為 card :
     card - 原生系統(tǒng)默認(rèn)的的跳轉(zhuǎn)
     modal - 只針對iOS平臺,模態(tài)跳轉(zhuǎn)
 headerMode - 頁面跳轉(zhuǎn)時,頭部的動畫模式,有 float 、 screen 、 none 三種:
     float - 漸變,類似iOS的原生效果
     screen - 標(biāo)題與屏幕一起淡入淡出
     none - 沒有動畫
 cardStyle - 為各個頁面設(shè)置統(tǒng)一的樣式,比如背景色,字體大小等
 transitionConfig - 配置頁面跳轉(zhuǎn)的動畫,覆蓋默認(rèn)的動畫效果
 onTransitionStart - 頁面跳轉(zhuǎn)動畫即將開始時調(diào)用
 onTransitionEnd - 頁面跳轉(zhuǎn)動畫一旦完成會馬上調(diào)用
 */

const AppNavigationStackConfigs = {
    initialRouteName: 'TabBar',
    initialRouteParams: {initParams: '初始化時傳遞參數(shù)'},
    navigationOptions: {
        title: '路由頁面的配置選項(xiàng),它會被 RouteConfigs 參數(shù)中的 navigationOptions 的對應(yīng)屬性覆蓋',
    },
    mode: 'card',
    headerMode: 'screen',
    transitionConfig: ()=>({
        screenInterpolator: CardStackStyleInterpolator.forHorizontal,
    }),
    onTransitionStart: (() => {
        console.log('頁面跳轉(zhuǎn)動畫開始');
    }),
    onTransitionEnd: (() => {
        console.log('頁面跳轉(zhuǎn)動畫結(jié)束');
    }),
};

export default {
    AppNavigationRouterConfigs,
    AppNavigationStackConfigs
};

tabBar.js

/**
 * Created by mymac on 2017/8/18.
 */

import React, { Component } from 'react';

import {TabBarBottom} from "react-navigation";

import Home from '../subTabBars/select';
import Follow from '../subTabBars/follow';
import Explor from '../subTabBars/explor';
import Mine from '../subTabBars/mine';

/*自定義的 tabBar 圖片 view*/
import TabBarItem from './tabBarItem';
/*
    創(chuàng)建下面的四個 tabar
*/
const AppRootTabBarRouteConfigs = {
    Home:{
        screen: Home,
        navigationOptions: {
            tabBarLabel: '首頁',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    focused={focused}
                    normalImage={require('../images/select.png')}
                    selectedImage={require('../images/select_select.png')}
                />
            ),
        }
    },
    Follow:{
        screen: Follow,
        navigationOptions: {
            tabBarLabel: '關(guān)注',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    focused={focused}
                    normalImage={require('../images/follow_follow.png')}
                    selectedImage={require('../images/follow_follow_select.png')}
                />
            ),
           tabBarOnPress:(obj)=>{
                console.log(obj);
                obj.jumpToIndex(obj.scene.index)
            },
        }
    },
    Explor:{
        screen: Explor,
        navigationOptions: {
            tabBarLabel: '發(fā)現(xiàn)',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    focused={focused}
                    normalImage={require('../images/explor_explor.png')}
                    selectedImage={require('../images/explor_explor_select.png')}
                />
            ),
        }
    },
    Mine:{
        screen: Mine,
        navigationOptions: {
            tabBarLabel: '我的',
            tabBarIcon: ({focused, tintColor}) => (
                <TabBarItem
                    focused={focused}
                    normalImage={require('../images/mine_mine.png')}
                    selectedImage={require('../images/mine_mine_select.png')}
                />
            ),
        }
    },
};

/*
 tabBarComponent - Tab選項(xiàng)卡組件,有 TabBarBottom 和 TabBarTop 兩個值,在iOS中默認(rèn)為 TabBarBottom ,在Android中默認(rèn)為 TabBarTop 。
 TabBarTop - 在頁面的頂部
 TabBarBottom - 在頁面的底部
 tabBarPosition - Tab選項(xiàng)卡的位置,有 top 或 bottom 兩個值
 swipeEnabled - 是否可以滑動切換Tab選項(xiàng)卡
 animationEnabled - 點(diǎn)擊Tab選項(xiàng)卡切換界面是否需要動畫
 lazy - 是否懶加載頁面
 initialRouteName - 初始顯示的Tab對應(yīng)的頁面路由名稱
 order - 用路由名稱數(shù)組來表示Tab選項(xiàng)卡的順序,默認(rèn)為路由配置順序
 paths - 路徑配置
 backBehavior - androd點(diǎn)擊返回鍵時的處理,有 initialRoute 和 none 兩個值
 initailRoute - 返回初始界面
 none - 退出

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

     用于 TabBarTop 時:
         activeTintColor - 選中的文字顏色
         inactiveTintColor - 未選中的文字顏色
         showIcon - 是否顯示圖標(biāo),默認(rèn)顯示
         showLabel - 是否顯示標(biāo)簽,默認(rèn)顯示
         upperCaseLabel - 是否使用大寫字母,默認(rèn)使用
         pressColor - android 5.0以上的MD風(fēng)格波紋顏色
         pressOpacity - android 5.0以下或者iOS按下的透明度
         scrollEnabled - 是否可以滾動
         tabStyle - 單個Tab的樣式
         indicatorStyle - 指示器的樣式
         labelStyle - 標(biāo)簽的樣式
         iconStyle - icon的樣式
         style - 整個TabBar的樣式

     用于 TabBarBottom 時:
         activeTintColor - 選中Tab的文字顏色
         activeBackgroundColor - 選中Tab的背景顏色
         inactiveTintColor - 未選中Tab的的文字顏色
         inactiveBackgroundColor - 未選中Tab的背景顏色
         showLabel - 是否顯示標(biāo)題,默認(rèn)顯示
         style - 整個TabBar的樣式
         labelStyle - 標(biāo)簽的樣式
         tabStyle - 單個Tab的樣式
 */

/*
 TabBarTop:
    indicatorStyle: {height: 0}, // android 中TabBar下面會顯示一條線,高度設(shè)為 0 后就不顯示線了, 不知道還有沒有其它方法隱藏???
    showIcon: true, // android 默認(rèn)不顯示 icon, 需要設(shè)置為 true 才會顯示
 */

const AppRootTabBarNavigatorConfigs = {
    initialRouteName: 'Home',
    defaultNavigationOptions: {
         headerStyle: {
             backgroundColor: '#f4511e',
         },
         headerTintColor: '#fff',
         headerTitleStyle: {
             fontWeight: 'bold',
         },
    },
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    lazy: true,
    tabBarOptions: {
        activeTintColor: 'red',
        inactiveTintColor: 'black',
        showLabel: true,
        style:{ // 在此處可以設(shè)置tabbar的屬性,height、marginBottom等。iPhone X適配時,需要在此處進(jìn)行適配處理
            backgroundColor: 'yellow',
        },
        labelStyle: {  // 在此處可以設(shè)置tabbar的title的屬性,大小、顏色等
            fontWeight: 'bold',
            fontSize: 12,
        },
        iconStyle: {
            // 在此處可以設(shè)置tabbar的icon的屬性
        }
    }
};

export default {
    AppRootTabBarRouteConfigs,
    AppRootTabBarNavigatorConfigs
};


/* 在此直接導(dǎo)出 Tab ,在 navigation 里面是得不到的,只有在 navigation 里面 調(diào)用構(gòu)造方法*/
/*
 構(gòu)造函數(shù)
 export default Tab = TabNavigator(AppTab.AppRootTabBarRouteConfigs, AppTab.AppRootTabBarNavigatorConfigs);
 */

二、傳值、回調(diào)

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
} from 'react-native';

export default class select extends Component {
    render() {
        const {navigate,} = this.props.navigation;
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    精選
                </Text>

                <TouchableOpacity style={{marginTop: 20}} onPress={()=>{

                    // 傳遞參數(shù),及 回調(diào)函數(shù)
                    navigate('First', {params: '你好第一頁', callBack:(value)=>{
                        console.log(value);
                    }});
                }}>
                    <Text style={styles.welcome}>
                        點(diǎn)擊跳轉(zhuǎn)到第一個頁面
                    </Text>
                </TouchableOpacity>

            </View>

        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    }
});



/**
 * Created by mymac on 2017/8/18.
 */
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TouchableOpacity
} from 'react-native';

export default class firstCtrl extends Component {

 
    render() {
        const {navigate} = this.props.navigation;
        // 收到的參數(shù)
        const {params} = this.props.navigation.state;

        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>
                    上一個頁面給當(dāng)前頁傳值為:{params.params}
                </Text>
                <TouchableOpacity style={{marginTop: 20}} onPress={()=>{

                    navigate('Second', {params: '你好第二頁'});

                }}>
                    <Text style={styles.welcome}>
                        點(diǎn)擊跳轉(zhuǎn)到第二個頁面
                    </Text>
                </TouchableOpacity>

                <TouchableOpacity style={{marginTop: 100}} onPress={()=>{
                    //回調(diào)函數(shù)
                    params.callBack('123456789');

                    this.props.navigation.goBack();

                }}>
                    <Text style={styles.welcome}>
                        點(diǎn)擊返回首頁,并傳值:"hello world"
                    </Text>
                </TouchableOpacity>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    }
});


三、每個頁面設(shè)置 navigator

 * Created by mymac on 2017/8/18.
 */
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TouchableOpacity
} from 'react-native';

export default class firstCtrl extends Component {

    /*
     title - 可以作為頭部標(biāo)題 headerTitle ,或者Tab標(biāo)題 tabBarLabel
     header - 自定義的頭部組件,使用該屬性后系統(tǒng)的頭部組件會消失
     headerTitle - 頭部的標(biāo)題,即頁面的標(biāo)題
     headerBackTitle - 返回標(biāo)題,默認(rèn)為 title
     headerTruncatedBackTitle - 返回標(biāo)題不能顯示時(比如返回標(biāo)題太長了)顯示此標(biāo)題,默認(rèn)為 “Back”
     headerRight - 頭部右邊組件
     headerLeft - 頭部左邊組件
     headerStyle - 頭部組件的樣式
     headerTitleStyle - 頭部標(biāo)題的樣式
     headerBackTitleStyle - 頭部返回標(biāo)題的樣式
     headerTintColor - 頭部標(biāo)題顏色
     headerPressColorAndroid - Android 5.0 以上MD風(fēng)格的波紋顏色
     gesturesEnabled - 否能側(cè)滑返回, iOS 默認(rèn) true , Android 默認(rèn) false
     */
/*
    static navigationOptions = ({ navigation, navigationOptions, screenProps }) => {
        return {
          title: navigation.getParam('otherParam', 'A Nested Details Screen'),
          headerRight: (
              <Text>right</Text>
          ),
          headerTitle: <customTitle/> 自定義標(biāo)題組件。
        };
    };
*/
    static navigationOptions = {
        title:'第一個頁面自定義標(biāo)題', // 或者 headerTitle:'第一個頁面自定義標(biāo)題'
        headerRight: (
            <Text>right</Text>
        ),
        //headerLeft: null, 沒有返回按鈕
        headerTintColor: 'red',
        header:null, // 隱藏 導(dǎo)航條
    };

    render() {
     
        return (
            <View style={styles.container}>
              
            </View>
        );
    }
}


四、navigation reset方法

import { NavigationActions } from 'react-navigation'

重新注冊導(dǎo)航棧,將原來的清空
const resetAction = NavigationActions.reset({
  index: 0, // 默認(rèn)選中第一個元素
  actions: [
    NavigationActions.navigate({ routeName: 'Profile'}) // Profile將這個js放入導(dǎo)航棧中
  ]
})
this.props.navigation.dispatch(resetAction)


import { NavigationActions } from 'react-navigation'

const resetAction = NavigationActions.reset({
  index: 1, // 默認(rèn)選中第二個 元素,  如果此處寫為 2  這越界了,因?yàn)橄旅鏃@镏挥袃蓚€元素
  actions: [
    NavigationActions.navigate({ routeName: 'Profile'}), //  Profile將這個js放入導(dǎo)航棧中,第一個元素
    NavigationActions.navigate({ routeName: 'Settings'}) // Settings將這個js放入導(dǎo)航棧中,第二個元素
  ]
})
this.props.navigation.dispatch(resetAction)


5、關(guān)于返回指定頁面(原)

原思路:每一個頁面進(jìn)行navigate的時候都有一個key,所以在使用goBack(key)的時候,只要知道要返回頁面的key就可以了。方法就是把頁面的key存起來,存在redux中

<Navigation onNavigationStateChange={(prevNav, nav, action)=>{
                            // 每次導(dǎo)航改變時,都會走這個方法,可以再次判斷邏輯,比如切換tabar需要調(diào)用方法
                            console.log('prevNav=',prevNav);
                            console.log('nav=',nav);
                            console.log('action=',action);

                            let route = {};
                            nav.routes.map((item)=>{
                                route[item.routeName] = item.key
                            });

                            console.log('route:',route);

                            this.props.saveRouteNameAndId(route);

                }}/>

5、關(guān)于返回指定頁面(新),請更新react-navigation到最新

再也不用去存key啦~

this.props.navigation 提供的幾種方法:

    goBack
    navigate
    pop
    popToTop
    getParam
    push
    replace

this.props.navigation.pop(2) // 2就是要返回幾個頁面

this.props.navigation.popToTop() // 直接返回到主導(dǎo)航

this.props.navigation.push('HomeDetail1') // push 和 navigate效果一樣

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

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

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