定制化你的ReactNative底部导航栏

栏目: 服务器 · 发布时间: 5年前

内容简介:​ 接触过ReactNative(以下简称RN)的大概都知道,分别是这样的尽管官方提供了导航栏的开箱即用方案,但是实际开发里面,我们会遇到各种各样的导航栏,各种各样的动效,所以以上可能无法满足我们的开发需求,我们就需要定制化的去做我们导航栏
定制化你的ReactNative底部导航栏

前言

​ 接触过ReactNative(以下简称RN)的大概都知道, react-navigation 提供了两种开箱即用的导航栏组件

分别是这样的

定制化你的ReactNative底部导航栏
定制化你的ReactNative底部导航栏

尽管官方提供了导航栏的开箱即用方案,但是实际开发里面,我们会遇到各种各样的导航栏,各种各样的动效,所以以上可能无法满足我们的开发需求,我们就需要定制化的去做我们导航栏

例如我们UI给我的导航栏样式

定制化你的ReactNative底部导航栏

我的内心: 这他么中间凸起的我怎么做,老子只是一个小前端,app很渣啊啊啊

定制化你的ReactNative底部导航栏

借助可爱的google,我找到了解决方法

就是

定制化你的ReactNative底部导航栏

TabBarComponent

这个api在文档资料很少,所以想要知道怎么用只能通过网络上的资源了

其中深受这篇文案的启发

Let's Create A Custom Animated Tab Bar With React Native

这位外国友人(话说reactnative在国外似乎还有点火),借助动画库 react-native-pose ,完成了这样的效果

定制化你的ReactNative底部导航栏

虽然是英文博客,但是配合翻译基本阅读无障碍,借助他的博客,我完成了ReactNative的自定义导航栏,效果如下

定制化你的ReactNative底部导航栏

自定义底部导航栏

createBottomTabNavigator
createBottomTabNavigator

增加底部导航器

import React from 'react'
import { createBottomTabNavigator } from 'react-navigation'
import Icon from '../Common/Icon' // 自定义图标库
import TabBar from '../Common/TabBar' // tabBarComponent 自定义组件
// 页面
import Category from '../View/TabBar/Category/Category'
import Main from '../View/TabBar/Main/Main'
import My from '../View/TabBar/My/My'
import OrderList from '../View/TabBar/OrderList/OrderList'
import OnlineDoctor from '../View/TabBar/OnlineDoctor/OnlineDoctor'
export default createBottomTabNavigator(
  {
    // 首页:
    one: {
      screen: Main,
      navigationOptions: () => {
        return {
          tabBarIcon: ({ tintColor }) => {
            var soureImge
            if (tintColor == '#CBCBCB') {
              soureImge = 'main'
            } else {
              soureImge = 'mainActive'
            }
            return <Icon name={soureImge} size={26} color={tintColor} />
          }
        }
      }
    },
    //分类:
     two: {
      screen: Category,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => {
          var soureImge
          if (tintColor == '#CBCBCB') {
            soureImge = 'Category'
          } else {
            soureImge = 'CategoryActive'
          }
          return <Icon name={soureImge} size={26} color={tintColor} />
        }
      }
    },
    //问诊:
    three: {
      screen: OnlineDoctor,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => {
          var soureImge
          if (tintColor == '#CBCBCB') {
            soureImge = 'onLine'
          } else {
            soureImge = 'onLineActive'
          }
          return <Icon name={soureImge} size={48} color={tintColor} />
        }
      }
    },
    // 购物篮: 
    four: {
      screen: OrderList,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => {
          var soureImge
          if (tintColor == '#CBCBCB') {
            soureImge = 'OrderList'
          } else {
            soureImge = 'OrderListActive'
          }
          return <Icon name={soureImge} size={26} color={tintColor} />
        }
      }
    },
    //我的:
    five: {
      screen: My,
      navigationOptions: () => {
        return {
          tabBarIcon: ({ tintColor }) => {
            var soureImge
            if (tintColor == '#CBCBCB') {
              soureImge = 'My'
            } else {
              soureImge = 'MyActive'
            }
            return <Icon name={soureImge} size={26} color={tintColor} />
          }
        }
      }
    }
  },
  {
    initialRouteName: 'one', // 初始化页面
    tabBarComponent: TabBar,
    tabBarOptions: {
      activeTintColor: '#F34C56',
      inactiveTintColor: '#CBCBCB'
    }
  }
)
        
复制代码

工具函数

图标没有使用图标库,直接搞一个图标库比较得心应手

../Common/Icon.js

import React from 'react'
import { Image } from 'react-native'
import { TabIcon } from './Image'

const Icon = ({ name, style, size }) => {
  const icon = TabIcon[name]
  return (
    <Image
      source={icon}
      style={[{ width: size, height: size }, style]}
    />
  )
}

export default Icon
复制代码

而对于图片则进行统一管理

../Common/Image.js

/**
 * 所有的图片资源都从这里统一管理
 */
// 底部导航栏的图片资源
export const TabIcon = {
  main: require('..'),
  mainActive: require('..'),
  Category: require('..'),
  CategoryActive: require('..'),
  onLine: require('..'),
  onLineActive: require('..'),
  OrderList: require('..'),
  OrderListActive: require('..'),
  My: require('..'),
  MyActive: require('..'),
}
复制代码

自定义底部导航器

万事俱备,下面就是自定义底部导航器了,就和定义 React 组件一样

import React from 'react'
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  TouchableNativeFeedback,
  Dimensions
} from 'react-native'
import posed from 'react-native-pose' // react-native 动画库

const Scaler = posed.View({ // 定义点击缩放
  active: { scale: 1 },
  inactive: { scale: 0.9 }
})

const TabBar = props => {
  const {
    renderIcon,
    getLabelText,
    activeTintColor,
    inactiveTintColor,
    onTabPress,
    onTabLongPress,
    getAccessibilityLabel,
    navigation
  } = props

  const { routes, index: activeRouteIndex } = navigation.state
  return (
    <Scaler style={Styles.container}>
      {routes.map((route, routeIndex) => {
        const isRouteActive = routeIndex === activeRouteIndex
        const tintColor = isRouteActive ? activeTintColor : inactiveTintColor
        return (
          <TouchableNativeFeedback
            key={routeIndex}
            style={Styles.tabButton}
            onPress={() => {
              onTabPress({ route })
            }}
            onLongPress={() => {
              onTabLongPress({ route })
            }}
            accessibilityLabel={getAccessibilityLabel({ route })}
          >
            {route.key == 'three' ? ( // 对特殊图标进行特殊处理
              <Scaler
                style={Styles.scalerOnline}
                pose={isRouteActive ? 'active' : 'inactive'}
              >
                {renderIcon({ route, focused: isRouteActive, tintColor })}
                <Text style={Styles.iconText}>{getLabelText({ route })}</Text>
              </Scaler>
            ) : ( // 普通图标普通处理
              <Scaler
                style={Styles.scaler}
                pose={isRouteActive ? 'active' : 'inactive'}
              >
                {renderIcon({ route, focused: isRouteActive, tintColor })}
                <Text style={Styles.iconText}>{getLabelText({ route })}</Text>
              </Scaler>
            )}
          </TouchableNativeFeedback>
        )
      })}
    </Scaler>
  )
}

const Styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    height: 53,
    borderWidth: 1,
    borderRadius: 1,
    borderColor: '#EEEEEE',
    shadowOffset: { width: 5, height: 10 },
    shadowOpacity: 0.75,
    elevation: 1
  },
  tabButton: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  spotLight: {
    width: tabWidth,
    height: '100%',
    justifyContent: 'center',
    alignItems: 'center'
  },
  spotLightInner: {
    width: 48,
    height: 48,
    backgroundColor: '#ee0000',
    borderRadius: 24
  },
  scaler: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  scalerOnline: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  iconText: {
    fontSize: 12,
    lineHeight: 20
  }
})

export default TabBar
复制代码

最后实现的效果就是

定制化你的ReactNative底部导航栏

如果你也有这样的需求,可以看看老外发布的那篇博客

Let's Create A Custom Animated Tab Bar With React Native

最后: 快要过年了,祝大家新年快乐


以上所述就是小编给大家介绍的《定制化你的ReactNative底部导航栏》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

React开发实战

React开发实战

[美] Cássio de Sousa Antonio / 杜伟、柴晓伟、涂曙光 / 清华大学出版社 / 2017-3-1 / 58.00 元

介绍如何成功构建日益复杂的前端应用程序与接口,深入分析 React库,并详述React生态系统中的其他工具与库,从而指导你创建完整的复杂应用程序。 你将全面学习React的用法以及React生态系统中的其他工具和库(如React Router和Flux 架构),并了解采用组合方式创建接口的佳实践。本书简明扼要地讲解每个主题,并呈现助你高效完成工作的细节。书中严谨深刻地讲述React中重要的功......一起来看看 《React开发实战》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具