Настройте нижнюю панель навигации ReactNative

React Native

предисловие

Те, кто сталкивался с ReactNative (далее RN), вероятно, знают, чтоreact-navigationПредоставляет два готовых компонента панели навигации.

соответственно вот так

createBottomTabNavigator

createMaterialBottomTabNavigator

Хотя официальное решение предоставляет готовое решение для панели навигации, в реальной разработке мы столкнемся с различными панелями навигации и различными динамическими эффектами, поэтому вышеперечисленное может не соответствовать нашим потребностям в разработке, нам потребуется настроить нашу навигацию. бар

Например, стиль панели навигации, который дает мне наш пользовательский интерфейс.

Мое сердце: что мне делать с выпуклостью посередине, я просто маленький передник, приложение отморозок

С помощью прекрасного Google я нашел обходной путь

то есть

TabBarComponent

Этот API имеет очень мало документации, поэтому, если вы хотите знать, как его использовать, вы можете использовать только ресурсы в сети.

Вдохновленный этим текстом

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

Этот иностранный друг (похоже, реактивнатив до сих пор горит за границей), с помощью анимационной библиотекиreact-native-pose, завершает этот эффект

Хотя это английский блог, он в основном доступен с переводом, С помощью его блога я завершил пользовательскую панель навигации ReactNative, эффект выглядит следующим образом

Настроить нижнюю панель навигации

  1. Настраиваемая нижняя панель навигации основана наcreateBottomTabNavigator, поэтому мы используем этот API для создания нижней панели навигации
  2. уточнитьcreateBottomTabNavigatortabBarComponent
  3. Нижняя панель навигации написана внутри tabBarComponent

Добавить нижний навигатор

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

Окончательный эффект

Если у вас тоже есть такие потребности, вы можете посмотреть блог, опубликованный иностранцами.

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

Наконец: приближается китайский Новый год, я желаю всем счастливого нового года