在某些情况下,默认的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了。

自定义react-navigation的TabBar的更多相关文章

  1. navigation和tabbar上的文字.图片 自定义

    [[UITabBarItem appearance] setTitleTextAttributes:@{ UITextAttributeTextColor : [UIColor blackColor] ...

  2. React Native常用组件之TabBarIOS、TabBarIOS.Item组件、Navigator组件、NavigatorIOS组件、React Navigation第三方

    以下内容为老版本React Native,faceBook已经有了新的导航组件,请移步其他博客参考>>[我是传送门] 参考资料:React Navigation  react-native ...

  3. react-native 学习 ----- React Navigation

    很久没有的登陆博客园了,密码都是找回的,从当年的大学生已经正常的走上了程序员的道路,看到之前发的博客还是写的android,现在自己已经在使用了react-native了. 大学毕业了,做了java后 ...

  4. react-native导航器 react navigation 介绍

    开发环境搭建好之后,想要进一步了解react-native,可以先从react-native官网上的电影列表案例入手: https://reactnative.cn/docs/0.51/sample- ...

  5. React Navigation & React Native & React Native Navigation

    React Navigation & React Native & React Native Navigation React Navigation https://facebook. ...

  6. [RN] 04 - React Navigation

    react-navigation和react-router的对比: 支持的平台: react-navigation: react-native react-router: react-native.r ...

  7. React-native 导航插件React Navigation 4.x的使用

    React-native 导航插件React Navigation 4.x的使用 文档 英文水平可以的话,建议直接阅读英文文档 简单使用介绍 安装插件 yarn add react-navigatio ...

  8. [RN] React Navigation 使用中遇到的显示 问题 汇总

    React Navigation 使用中遇到的显示 问题 汇总 https://www.jianshu.com/p/8b1f18affc5d

  9. WijmoJS 中自定义 React 菜单和列表项模板

    WijmoJS 中自定义 React 菜单和列表项模板 在V2019.0 Update2 的全新版本中,React 框架下 WijmoJS 的前端UI组件功能再度增强. WijmoJS的菜单和类似列表 ...

  10. react navigation goBack()返回到任意页面(不集成redux) 一

    方案一: 一.适用场景:在app端开发的时候,相反回到某一个页面的时候保持跳转页面的所有状态不更新,也就是说不触发新的生命周期. 例如:A——>B——>C——>D 要想从D页面直接返 ...

随机推荐

  1. C# 读取TXT文本数据 添加到数据库

    protected void Button1_Click(object sender, EventArgs e) { //使用FileStream读取文件 FileStream fileStream ...

  2. docker学习-常用命令2

    三.容器管理命令3.1 Docker commit 命令,从容器创建一个新的镜像.OPTIONS说明: -a :提交的镜像作者: -c :使用Dockerfile指令来创建镜像: -m :提交时的说明 ...

  3. pycharm 配置svn

    1.找到本地svn.exe 2.配置svn路径 3.输入svn路径,然后会进行密码校验 问题 本地的TortoiseSVN在bin目录没有发现svn.exe 原因: 安装TortoiseSVN的时候 ...

  4. NetCore+MySql+EF 数据库生成实体模型

    NetCore版本    2.1 1.点击“工具”->“NuGet包管理器”->“程序包管理器控制台” 分别安装以下几个包 Mysql 版本: MySql.Data.EntityFrame ...

  5. pwnable.kr-passcode-witeup

    进入远端运行, 废话不多说,下载下来分析. 根据提示,编译一下子. 知道问题了. 想象着,输入的值到了passcode1和passcode2的值作为地址的地方,passcode1处刚输入值时,程序终止 ...

  6. 算法练习LeetCode初级算法之设计问题

    打乱数组 不断的让第一个与后面随机选择的数交换 class Solution { private int[] nums; private int[] initnums; public Solution ...

  7. lets encrypt与openssl结合实现双认证

    lets encrypt,是一个免费的证书认证机构,不需要导入根证书.但是这个认证机构只能认证服务端的,如果想要实现双认证,lets encrypt就不行了. openssl可以自签发,可以进行双认证 ...

  8. 010 Editor 8.0.1 之 暴力破解

    一.工具及软件介绍二.破解1.打开调试程序2.打开注册页面3.在弹出窗口API中下断4.点击注册按钮5.逐一进去观察6.找到正确的授权字符串7.找到函数头8.找到计算出EBX的CALL9.进入函数跟踪 ...

  9. CSS中的字体描边

    兴趣使然,突然看见网上的一些带有描边的字体,觉得有点意思,便尝试去做了下 不是什么很厉害的技巧,当然也有参考张鑫旭大神写的文章 只能感叹,css的世界还很大,很广阔 直入主题: 对于文字的描边,一般都 ...

  10. 防止网页被别人的网站iframe,服务端如何设置HTTP头部中的X-Frame-Options信息?

    一.现象:in a frame because it set 'X-Frame-Options' to 'deny'. 二.服务配置 因为,有时候为了防止网页被别人的网站iframe,我们可以通过在服 ...