自定義react-navigation的TabBar


在某些情況下,默認的react-navigation的tab bar無法滿足開發者的要求。這個時候就需要自定義一個tab bar了。本文就基於react-navigtion v2來演示如何實現一個自定義tab bar。

這里主要處理的是再android里,當界面中有輸入框,喚起軟鍵盤的時候位於底部的tab bar也會浮動到鍵盤的上方。這顯然不是我們需要的。所以,需要用自定義的tab bar來解決這個問題。

Keyboard模塊

問題是,有鍵盤的時候tabbar會被頂起來,鍵盤消失的時候tab bar也會恢復到正常的位置。
那么處理這個問題的最好辦法就是,當鍵盤喚起的時候讓tab bar不可見,當鍵盤消失當時候再讓tab bar顯示出來。

這就需要用到Keyboard了。

import { Keyboard } from 'react-native';

Keyboard模塊專門用來處理鍵盤事件。通過這個模塊我們就可以得知鍵盤要喚起,還是要消失。

import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';

class Example extends Component {
  componentDidMount () {
    this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
    this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
  }

  componentWillUnmount () {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
  }

  _keyboardDidShow () {
    alert('Keyboard Shown');
  }

  _keyboardDidHide () {
    alert('Keyboard Hidden');
  }

  render() {
    return (
      <TextInput
        onSubmitEditing={Keyboard.dismiss}
      />
    );
  }
}

componentDidMount的時候綁定鍵盤的兩個事件:

  1. keyboardDidShow, 鍵盤即將出現
  2. keyboardDidHide, 鍵盤即將隱藏

通過Keyboard模塊綁定了這兩個事件之后就可以在綁定的回調里讓tab bar顯示和隱藏了。

自定義tab bar

在react-navigation v2中,要實現自定義的tab bar非常簡單:

import {
  createBottomTabNavigator,
  createStackNavigator,
} from 'react-navigation';

class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Details!</Text>
      </View>
    );
  }
}

class HomeScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

class SettingsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Go to Details"
          onPress={() => this.props.navigation.navigate('Details')}
        />
      </View>
    );
  }
}

const HomeStack = createStackNavigator({
  Home: HomeScreen,
  Details: DetailsScreen,
});

const SettingsStack = createStackNavigator({
  Settings: SettingsScreen,
  Details: DetailsScreen,
});

export default createBottomTabNavigator(
  {
    Home: HomeStack,
    Settings: SettingsStack,
  },
  {
    /* Other configuration remains unchanged */
  }
);

這里創建了一個每一個tab項都是一個stack navigator的tab bar。這里當然使用的是默認的tab bar。方法createBottomTabNavigator會返回一個在底部的tab bar。

我們來添加一個自定義的tab bar:

// ...略...

export default createBottomTabNavigator(
  {
    Home: HomeStack,
    Settings: SettingsStack,
  },
  {
    tabBarComponent: CustomTabComponent,
  }
);

CustomTabView就是自定義的tab bar。

當程序運行起來以后,react-navigation會把tab bar所需要的內容(tab的label、icon、navigate到什么地方等都通過prop的方式傳進來)。但是,我們這里並不打算做其他的定制,所以可以通過一個簡單的方式把這些tab bar的item都繪制出來。

這就需要用到react-navigation-tabs。這個包提供了tab bar的所有默認的實現。包括上面提到的props的解析都有。看下代碼:

import React from 'react';
import { Keyboard } from 'react-native';
import { BottomTabBar } from 'react-navigation-tabs';

type Prop = {};
type State = { visible: boolean };

export default class CustomTabComponent extends React.Component<Prop, State> {
  state: State = { visible: true };

  componentDidMount() {
    this.kbShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardWillShow);
    this.kbHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardWillHide);
  }

  keyboardWillShow = () => {
    console.log('keyboardwillshow');
    this.setState({ visible: false });
  };

  keyboardWillHide = () => {
    console.log('keyboardwillhide');
    this.setState({ visible: true });
  };

  componentWillUnmount() {
    this.kbShowListener.remove();
    this.kbHideListener.remove();
  }

  render() {
    return this.state.visible && <BottomTabBar {...this.props} />;
  }
}

在keyboard顯示的時候隱藏tab bar:

  keyboardWillShow = () => {
    this.setState({ visible: false });
  };

在鍵盤隱藏的時候顯示tab bar:

  keyboardWillHide = () => {
    this.setState({ visible: true });
  };

顯示出全部的tab item:

  render() {
    return this.state.visible && <BottomTabBar {...this.props} />;
  }

最后

處理軟鍵盤導致的tab bar上浮這個問題就完美解決了。其他的很多時候軟鍵盤的出現都會導致類似的問題。基本上都可以通過綁定Keyboard模塊的方式來解決。

對於tab bar本身有定制需要的,則可以通過自定義tab bar實現。正好本文解決了軟鍵盤對tab bar的影響,也開是了一個解決自定義tab bar的門。有深度定義tab bar的同學,就需要解析從react-navigation傳過來的props了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM