關於react native android navigationBar的隱藏問題

在IOS上,react native有官方的TabBar使用,可是android,就須要使用第三方插件或者本身手寫了。react

我在項目中使用了react-native-scrollable-tab-view插件,可是在使用過程當中,遇到了一些問題,沒法知足個人需求,android

因而在這篇文章中記錄一下個人使用心得。ios

使用了react-native-vector-icons插件git

參kao的開源項目:使用reactNative實現的GitHub客戶端資訊頭條github


個人項目需求:react-native

和IOS同樣,使用tabBar,底部有兩個tab(主頁個人),在個人頁面中,不須要頂部標題,而切換到其餘頁面時,須要隱藏底部tabBar。app

在使用react-native-scrollable-tab-view插件時,若是將整個tab插件放在Navigator中,那麼在切換底部tab的時候,標題欄的標題沒法進行切換,而若是將Navigator放在Tab內部,那麼底部TabBar沒法隱藏。ide

上面就是示意圖,下面就是代碼了
flex

關鍵點就是須要根據須要隱藏標題動畫

_setNavigatorRef = (navigator) => {
        if (navigator !== this._navigator) {
            this._navigator = navigator;
            if (navigator) {
                // Observe focus change events from the owner.
                this._listeners = [
                    navigator.navigationContext.addListener('willfocus', this._onWillFocus),
                ];
            }
        }
    }
    ......
    componentWillUnmount() {
        this._listeners && this._listeners.forEach(listener => listener.remove());
    }

    _onWillFocus = (event) => {
        if(event.data.route.id == 'main') {
            this.setState({
                hideNavBar: true,
            });
        } else {
            this.setState({
                hideNavBar: false,
            });
        }
    }
    ......
    navBar() {
        if(!this.state.hideNavBar) {
            return (
                <Navigator.NavigationBar
                    routeMapper={{
                        LeftButton: this.LeftButton,
                        RightButton: this.RightButton,
                        Title: this.Title
                    }}
                    style={styles.navBar}
                    navigationStyles={NavigatorNavigationBarStyle} //頁面切換的動畫效果
                />
            )
        } else {
            return <Text style={{height:0, position:'absolute', top:0}} />;
        }
    }

index.android.js

import React, {
    AppRegistry,
    Component,
    StyleSheet,
    Text,
    View,
    TouchableOpacity,
    Platform,
    Navigator
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import NavigatorNavigationBarStyle from './LLNavigatorBarStyle';
import Main from './Main';
import TwoView from './TwoView';
import Three from './Three';
class reactNative23 extends Component {
    constructor(props) {
        super(props);
        this.state = {
            hideNavBar: true,
            starDatas: null,
        };
    }

    renderScene = (route, navigator) => {
        switch(route.id) {
            case 'two': 
                return <TwoView navigator={navigator}/>
            case 'three': 
                return <Three navigator={navigator}/>
            default:
                return <Main navigator={navigator}/>
        }
    }
    componentWillUnmount() {
        this._listeners && this._listeners.forEach(listener => listener.remove());
    }

    _onWillFocus = (event) => {
        if(event.data.route.id == 'main') {
            this.setState({
                hideNavBar: true,
            });
        } else {
            this.setState({
                hideNavBar: false,
            });
        }
    }

    _setNavigatorRef = (navigator) => {
        if (navigator !== this._navigator) {
            this._navigator = navigator;
            if (navigator) {
                // Observe focus change events from the owner.
                this._listeners = [
                    navigator.navigationContext.addListener('willfocus', this._onWillFocus),
                ];
            }
        }
    }
    // Nav使用
    navBar() {
        if(!this.state.hideNavBar) {
            return (
                <Navigator.NavigationBar
                    routeMapper={{
                        LeftButton: this.LeftButton,
                        RightButton: this.RightButton,
                        Title: this.Title
                    }}
                    style={styles.navBar}
                    navigationStyles={NavigatorNavigationBarStyle} //頁面切換的動畫效果
                />
            )
        } else {
            return <Text style={{height:0, position:'absolute', top:0}} />;
        }
    }

    LeftButton(route, navigator, index, navState) {
      return (
        <TouchableOpacity
          onPress={() => navigator.pop()}
          style={styles.navBarLeftButton}>
          <Icon
              name='ios-arrow-left'
              size={30}
              color='#fff'
              style={styles.icon}
          />
        </TouchableOpacity>
      );
  }
    RightButton(route, navigator, index, navState) {
        return null;
    }

    Title(route, navigator, index, navState) {
        return (
            <View style={styles.navBarText}>
                <Text style={styles.navBarTitleText} numberOfLines={1}>
                    {route.title}
                </Text>
            </View>
            
        );
    }
    /**
     * 路由轉跳的效果,默認是FadeAndroid
     */
    configureScene(route, routeStact) {
        //若是路由有傳 切換方式,則使用
        if (route.configureScene) {
            return route.configureScene;
        } else {
            return Navigator.SceneConfigs.FadeAndroid;
        }
    }
    render() {
        return (
            <Navigator
                ref={this._setNavigatorRef}
                debugOverlay={false}
                configureScene={this.configureScene.bind(this)}
                style={styles.appContainer}
                //sceneStyle={this.state.hideNavBar ? {marginTop: 0} : styles.sceneStyle} //全部容器的樣式
                initialRoute={{id: 'main'}}
                renderScene={this.renderScene}
                navigationBar={this.navBar()}
                />
        );
    }
}

const styles = StyleSheet.create({
    navBar: {
        backgroundColor:'#fe4500',
        height: (Platform.OS === 'ios') ? 64 : 50
    },
    navBarText: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        width: 250,

    },
    navBarTitleText: {
        color: '#fff',
        fontSize: 16,
        fontWeight: '500',
        textAlign: 'center',
        marginHorizontal: 10,
        marginVertical: 11,
    },
    navBarLeftButton: {
        paddingLeft: 10,
        width: 40,
        height: 50,
    },
    navBarRightButton: {
        marginRight:5,
    },
    icon: {
        
        marginTop:(Platform.OS === 'ios') ? 6: 8,
        textAlign:'center'
    }
});

AppRegistry.registerComponent('reactNative23', () => reactNative23);

Main.js

import React, {
	Component,
} from 'react-native';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import Home from './Home';
import My from './My';
import TabBar from './TabBar';
export default class Main extends Component {

	render() {
		return (
			<ScrollableTabView
				tabBarPosition='bottom'
				renderTabBar={() => <TabBar />}
				locked={true}
			>
			<Home navigator={this.props.navigator} tabLabel={{tabName: '主頁', iconName: 'ios-home'}}/>
			<My navigator={this.props.navigator} tabLabel={{tabName: '個人', iconName: 'ios-person'}}/>
			</ScrollableTabView>
		)
	}
}

Home.js

import React, {
	Component,
	View,
	TouchableOpacity,
	StyleSheet,
	Text
} from 'react-native';
export default class Home extends Component {

	toTwo = () => {
		this.props.navigator.push({
			id: 'two',
			title: '第二頁面'
		})
	}

	render() {
		return (
			<View style={styles.container}>
				<View style={styles.header}>
					<Text style={{color: '#fff', fontSize: 16, fontWeight: '500',}}>主頁</Text>
				</View>
				<View style={styles.content}>
					<TouchableOpacity onPress={this.toTwo} style={styles.button}>
						<Text>跳轉到第二頁</Text>
					</TouchableOpacity>
				</View>
				
			</View>
		)
	}
}

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

	header: {
		backgroundColor: '#fe4500',
		height: 50,
		
		justifyContent: 'center',
		alignItems: 'center'
	},
	content: {
		flex: 1,
		justifyContent: 'center',
		alignItems: 'center',
	},
	button: {
		justifyContent: 'center',
		alignItems: 'center',
		height: 50,
		width: 200,
		backgroundColor: '#fe4500',
	}
})

不過,這不是最好的解決辦法,應該在返回Main頁面時,應該Home頁面的標題不是NavigationBar,因此會有0.4秒的白屏出現,固然,若是你的項目頂部標題欄是白色的,那就看不出來了。

ps:大概就是這樣了,若是你看不懂,請不要吐槽個人表達能力以及排版

相關文章
相關標籤/搜索