react native 開發APP(四)頁面導航, Tabbar, Navigation

react native 頁面跳轉,Tabbar,Navigation

官網 https://reactnative.cn/

項目下載地址:https://github.com/hebiao6446/DemoProject
陸續更新中。。。

1.先看效果,找一個演示的炮灰

在這裏插入圖片描述

我們至少可以看到兩點
1) 目前大部分市場上的APP都是這種結構Tabbar欄+導航欄
2) 從閃屏頁面(廣告業)到進入APP並不是頁面跳轉,更多的是有點像場景切換的一個過程
帶着這個嚴肅的問題我們來搞一搞我們的代碼

2.react native 的Tabbar 和Navigation

a.react native 創建BottomTabbar

UITabbarController 是iOS系統自帶的組件,這個對於每個iOS開發者來說應該是比較熟悉的,但是在 react native裏面其實系統也提供了類似的東西

https://github.com/react-navigation/tabs

https://github.com/react-navigation/react-navigation
一個是管理BottomTabbar, 一個是管理導航的
這裏有一段話 , 請注意下
在這裏插入圖片描述
點進去,我們發現了這個東西
https://reactnavigation.org/docs/getting-started/
在這裏插入圖片描述
也就是你最好先安裝這些東西再安裝BottomTabbar

yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

在這裏插入圖片描述

執行完上面的命令以後
再執行 下面兩條命

yarn add react-navigation
yarn add react-navigation-tabs

在這裏插入圖片描述
安裝完成以後別忘記進入ios目錄 cocopad install下

$ cd ios/
$ pod install 

github其實已經給出了, 但是並非拿來主義的給出,那麼這個時候就可以使用BottomTabbar 這個東西了 。。。。
但是這個東西我們的理解就是一個控制器,控制器是需要頁面來支持的。。 我們來搞四個頁面
在這裏插入圖片描述

import BaseComponet from "./BaseComponet";
import {Image, StyleSheet, View} from "react-native";
import React from "react";

export default class FirstView  extends BaseComponet{
    render(){
        return (
            <View style={styles.contain}>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    contain:{
        background:'#0000ff',
        flex:1,
    },
});

弄個簡單的頁面 ,然後把BottomTabbar 關聯起來
在這裏插入圖片描述

import {Image, Text, View, StyleSheet, DeviceEventEmitter} from "react-native";
import React from "react";
import {createBottomTabNavigator} from "react-navigation-tabs";
import HbColor from "../utils/HbColor";
import HbImages from "../utils/HbImages";

import FirstView from "./FirstView";
import SecondView from "./SecondView";
import ThirdView from "./ThirdView";
import FourthView from "./FourthView";

const RootTabbar = createBottomTabNavigator(
    {
        First:{
            screen:FirstView,
            navigationOptions:{
                tabBarLabel:'一',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar1}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        },
        Second:{
            screen:SecondView,
            navigationOptions:{
                tabBarLabel:'two',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar2}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        },
        Third:{
            screen:ThirdView,
            navigationOptions:{
                tabBarLabel:'삼',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar3}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        },
        Fourth:{
            screen:FourthView,
            navigationOptions:{
                tabBarLabel:'よん',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar3}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        }
    },
    {
        initialRouteName:'First',
        order:['First','Second','Third','Fourth'],
        tabBarOptions:{
            activeTintColor:HbColor.COLOR_DEF,
            activeBackgroundColor:'#00000000',
            inactiveTintColor:HbColor.COLOR_abaaaa,
            inactiveBackgroundColor:'#00000000',
            showLabel:true,
            showIcon:true,
            style:{
                // borderTopColor: 'red',
                height: 49,
            },
            tabStyle:{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center',
            },
            labelStyle:{
                fontSize:11,
            },
            allowFontScaling:false,

        },
        defaultNavigationOptions:({navigation})=>({
            tabBarVisible:true,
            tabBarIcon:({focused, horizontal, tintColor })=>{
                const { routeName } = navigation.state; // 選項卡名稱
                let textStyle = {};
                if(focused){
                    textStyle = {
                        color: 'red'
                    };
                }
                return(
                    <View>
                        <Text style={textStyle}>{routeName}-Icon</Text>
                    </View>
                );

            },
            tabBarLabel:({focused, tintColor})=>{
                const { routeName } = navigation.state; // 選項卡名稱
                console.log(focused); // 是否處於活動狀態,是爲true
                console.log(tintColor); // 狀態顏色值
                return(
                    <View>
                        <Text>{routeName}-Label</Text>
                    </View>);
            }
        })
    }
);

const TabbarStyles = StyleSheet.create({
    tabbarSelect:{
        tintColor: HbColor.COLOR_DEF,
        height:'70%',
        resizeMode:'contain',
    },
    tabbleUnselect:{
        tintColor: HbColor.COLOR_abaaaa,
        height:'70%',
        resizeMode:'contain',
    }
})

export default RootTabbar;

然,這個並沒有完成,也就是我們現實是把底部的Tabbar和頁面關聯在一起了,那麼新的問題來了, 怎麼讓react native知道這東西是項目的入口了 ?? 這個時候我們需要把之前的廣告也和引導頁關聯起來
剛剛上面我們用到了一個函數

createBottomTabNavigator  

這個東西可以理解爲創建底部的Tabbar切換欄, 那麼如何將這個東西告訴react native了 ?這裏面就涉及到另外一個函數

createSwitchNavigator

可以理解爲控制器切換函數, 會默認一個控制器 ,這個就跟之前的廣告也有關係了 。。。 貼代碼

const navi = createSwitchNavigator({
    //所有切換控制器列表
    Launch:ADView,
    Tabbar:{
        screen:RootTabbar,
    },
},{
    //默認的控制器名稱
    initialRouteName:'Tabbar',
});
const  App = createAppContainer(navi);
export default App;

代碼貼出來了。 看效果 。。。
在這裏插入圖片描述

import React, {Component} from 'react';
import {View, StyleSheet, Text} from 'react-native';
import GuideGroup from './appcode/GuideGroup';
import ADView from "./appcode/ADView";
import RootTabbar from "./appcode/myview/ARootTabbar";

import {createAppContainer,createSwitchNavigator} from 'react-navigation'
/*
class App extends Component{
  render() {
    return (
        <View style={styles.view1}>
        <ADView/>
        </View>
  )
  }
}
const styles = StyleSheet.create({
  view1:{
    flex:1,
    justifyContent:'center',
  }
});
export default App;
*/
const navi = createSwitchNavigator({
    //所有切換控制器列表
    Launch:ADView,
    Tabbar:{
        screen:RootTabbar,
    },
},{
    //默認的控制器
    initialRouteName:'Tabbar',
});
const  App = createAppContainer(navi);
export default App;

這是首頁代碼,有圖有代碼基本上就沒什麼了吧 。。。

項目下載地址:https://github.com/hebiao6446/DemoProject
陸續更新中。。。

`b.react native 創建導航條

在這裏插入圖片描述
意味着啥了 ??? 意味着頁面不能跳轉,這個就麻煩了。。。不能跳轉頁面還搞個錘子了。。。 也就是我們需給頁面加入導航條
地址先奉上,然後就是下載按鈕插件了。 。。
https://reactnavigation.org/docs/stack-navigator/

yarn add react-navigation-stack @react-native-community/masked-view

安裝上面的導航器 ,然後稍稍修改下代碼

import BaseComponet from "./BaseComponet";
import {Image, StyleSheet, View} from "react-native";
import React from "react";
import {createStackNavigator} from "react-navigation-stack";
import HbColor from "../utils/HbColor";
class FirstView  extends BaseComponet{
    render(){
        return (
            <View style={styles.contain}>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    contain:{
        backgroundColor:'#ff000022',
        flex:1,
    },
});
const FirstNavi = createStackNavigator({
    First: {
        screen: FirstView,
        navigationOptions: {
            title: '第一頁',
            headerStyle: {
                backgroundColor: HbColor.COLOR_e85b53,
            },
            headerTintColor: '#ffffff',
        },
    },
}, {
    navigationOptions: ({
                            navigation
                        }) => ({
                        // 二級頁面隱藏Tabbar
        tabBarVisible: navigation.state.index > 0 ? false : true,
    })
});
export default FirstNavi;

四個頁面都需要改成這個樣的, 也就是需要在外面包裝一層
createStackNavigator這東西

import {Image, Text, View, StyleSheet, DeviceEventEmitter} from "react-native";
import React from "react";
import {createBottomTabNavigator} from "react-navigation-tabs"
import HbColor from "../utils/HbColor";
import HbImages from "../utils/HbImages";

// import FirstView from "./FirstView";
// import SecondView from "./SecondView";
// import ThirdView from "./ThirdView";
// import FourthView from "./FourthView";
import FirstNavi from "./FirstView";
import SecondNavi from "./SecondView";
import ThirdNavi from "./ThirdView";
import FourthNavi from "./FourthView";
const RootTabbar = createBottomTabNavigator(
    {
        First:{
            screen:FirstNavi,
            navigationOptions:{
                tabBarLabel:'一',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar1}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        },
        Second:{
            screen:SecondNavi,
            navigationOptions:{
                tabBarLabel:'two',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar2}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        },
        Third:{
            screen:ThirdNavi,
            navigationOptions:{
                tabBarLabel:'삼',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar3}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        },
        Fourth:{
            screen:FourthNavi,
            navigationOptions:{
                tabBarLabel:'よん',
                tabBarIcon: ({ tintColor, focused }) => {
                    return <Image
                        source={HbImages.img_tabbar3}
                        style={focused?TabbarStyles.tabbarSelect:TabbarStyles.tabbleUnselect}
                    />
                }
            }
        }
    },
    {
        initialRouteName:'First',
        order:['First','Second','Third','Fourth'],
        tabBarOptions:{
            activeTintColor:HbColor.COLOR_DEF,
            activeBackgroundColor:'#00000000',
            inactiveTintColor:HbColor.COLOR_abaaaa,
            inactiveBackgroundColor:'#00000000',
            showLabel:true,
            showIcon:true,
            style:{
                // borderTopColor: 'red',
                height: 49,
            },
            tabStyle:{
                flex: 1,
                justifyContent: 'center',
                alignItems: 'center',
            },
            labelStyle:{
                fontSize:11,
            },
            allowFontScaling:false,

        },
        defaultNavigationOptions:({navigation})=>({
            tabBarVisible:true,
            tabBarIcon:({focused, horizontal, tintColor })=>{
                const { routeName } = navigation.state; // 選項卡名稱
                let textStyle = {};
                if(focused){
                    textStyle = {
                        color: 'red'
                    };
                }
                return(
                    <View>
                        <Text style={textStyle}>{routeName}-Icon</Text>
                    </View>
                );

            },
            tabBarLabel:({focused, tintColor})=>{
                const { routeName } = navigation.state; // 選項卡名稱
                console.log(focused); // 是否處於活動狀態,是爲true
                console.log(tintColor); // 狀態顏色值
                return(
                    <View>
                        <Text>{routeName}-Label</Text>
                    </View>);
            }
        })
    }
);
const TabbarStyles = StyleSheet.create({
    tabbarSelect:{
        tintColor: HbColor.COLOR_DEF,
        height:'70%',
        resizeMode:'contain',
    },
    tabbleUnselect:{
        tintColor: HbColor.COLOR_abaaaa,
        height:'70%',
        resizeMode:'contain',
    }
})

export default RootTabbar;

最後就是上效果了。。。。
在這裏插入圖片描述

3.react native 的從引導頁(廣告頁)進入APP

這個問題我們先回到原始的開發中 ,原生的開發,從廣告頁面或者引導頁面進入APP正題的話
1) Android的引導頁是一個Activity,進入APP正題以後直接finish
2)iOS的引導頁很多人會在Window上鋪一個圖層,進入APP正題後隱藏圖層

react native咋搞得了 ? 我之所以寫react native系列的APP開發,是因爲我在接手別人的react(不是react native)項目的時候往手機APP開發方向稍微有點研究,就一個廣告頁面跳轉到APP正題 大部分寫的文章純瞎幾把搞 , 不告訴你版本,不告你你 相關鏈接。。那麼我只有自己抽空寫一寫相關的文章了 。
react native提供類似一個控控制器切換器的東西

const navi = createSwitchNavigator({
    //所有切換控制器列表
    Launch:ADView,
    Tabbar:{
        screen:RootTabbar,
    },
},{
    //默認的控制器
    initialRouteName:'Launch',
});
const  App = createAppContainer(navi);
export default App;

也就是我們在ADView這個頁面是需要觸發切換到Tabbar頁面的 ,
這個ADView頁面就是廣告也或者引導頁面,我們來把這個頁面規劃下

import React, {Component} from 'react';
import {
    SafeAreaView,
    StyleSheet,
    StatusBar, DeviceEventEmitter,
} from 'react-native';
import ADView from "./ADView";
import GuideGroup from "./GuideGroup";
import ADUtil from "./utils/ADUtil";
class LaunchView extends Component{
    constructor(pros){
        super(pros);
        this.state={
            isFirstLoad:true,
        };
        this.onEnterHome = this.onEnterHome.bind(this);
    }
    onEnterHome(){
        const {navigate} = this.props.navigation;
        navigate('Tabbar');
    }
    render(){
        let mView = this.state.isFirstLoad ?  <GuideGroup  onButtonClick = {this.onEnterHome} /> :  <ADView  onButtonClick = {this.onEnterHome} /> ;
        return (
            <>
                <StatusBar barStyle="dark-content"
                           backgroundColor="blue"
                />
                <SafeAreaView style={styles.container}>
                    {mView}
                </SafeAreaView>
            </>
        );
    }

    componentDidMount(): void {
        ADUtil.ftStart().then((res)=>{
            if (res == 'false'){
                this.setState({
                    isFirstLoad:false,
                })
            }
        }).catch((e)=>{

        });
    }

}

const styles = StyleSheet.create({
    container:{
        flex:1,
    },

});

export default LaunchView;

LaunchView這個頁面其實包含兩個部分,第一次啓動APP的引導頁面和廣告頁面,上篇文章說到,引導頁面和廣告頁面是互斥的,所以說我們可以把兩個頁面合在一起。我們來看下效果圖
在這裏插入圖片描述
警告⚠️我們就忽略了。。
這裏有個重點, 也就是從廣告頁面跳轉到 Tabbar頁面

onEnterHome(){
        const {navigate} = this.props.navigation;
        navigate('Tabbar');
    }

這個方法我們注意到一個Tabbar是我們前面自定義的一個名稱

const navi = createSwitchNavigator({
    //所有切換控制器列表
    Launch:LaunchView,
    Tabbar:{
        screen:RootTabbar,
    },
},{
    //默認的控制器
    initialRouteName:'Launch',
});
const  App = createAppContainer(navi);
export default App;

那麼現在這個函數的功能我們就一目瞭然了, createSwitchNavigator這東西創建了兩個控制器,一個是引導頁(廣告頁面),一個是Tabbar 。引導頁(廣告頁面)可以通過點擊進入Tabbar頁面,也可以倒計時讀秒進入。

在這裏插入圖片描述

項目下載地址:https://github.com/hebiao6446/DemoProject
陸續更新中。。。

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