如何在 React Native 中自定义材质底部选项卡导航器?

时间:2021-04-26 03:36:07

标签: react-native react-navigation customization react-navigation-bottom-tab

我正在尝试将材质底部选项卡导航器的颜色自定义为 LinearGradient。

为了实现这一点,我使用了 expo-linear-gradient,我使用 props 来传递方法,但我不知道如何在 customTabBar 函数中访问这些 props。 >

这是我的包含标签的代码

import React from "react";
import { View, Text, StyleSheet, Image, ImageBackground } from "react-native";
import { createMaterialBottomTabNavigator } from "@react-navigation/material-bottom-tabs";

import MainHomeScreen from "./MainHomeScreen";
import CustomTabBar from "./CustomTabBar";

import * as Icons from "@expo/vector-icons";
import { LinearGradient } from "expo-linear-gradient";

const Tab = createMaterialBottomTabNavigator();

const BottomTabScreen = () => {
  return (
    <>
      <Tab.Navigator
        screenOptions={{ tabBarLabel: false }}
        barStyle={(props) => <CustomTabBar {...props} />}
      >
        <Tab.Screen
          name="MainHomeScreen"
          component={MainHomeScreen}
          options={{
            tabBarIcon: ({ focused }) => (
              <>
                <Icons.Feather name="home" color="#fff" size={24} />
              </>
            ),
          }}
        />
      </Tab.Navigator>
    </>
  );
};

export default BottomTabScreen;

const styles = StyleSheet.create({
  shadow: { elevation: 5 },
  dot: {
    width: 4,
    height: 4,
    borderRadius: 7,
    marginTop: 5,
    backgroundColor: "#fff",
  },
  linearGradient: {
    height: 30,
    width: 50,
  },
});

这是自定义标签栏的代码:

import React from "react";
import { View, Text, StyleSheet } from "react-native";

const CustomTabBar = ({ state, navigationState }) => {
  console.log(navigationState);
  return <View style={styles.tabs}>
    {state.route.map((route, index) => {
      
    })}
  </View>;
};

export default CustomTabBar;

const styles = StyleSheet.create({
  tabs: {
    position: "absolute",
    bottom: 15,
    left: 20,
    right: 20,
    elevation: 2,
    borderRadius: 20,
    backgroundColor: "transparent",
    borderTopLeftRadius: 15,
    borderTopRightRadius: 15,
    overflow: "hidden",
  },
});

2 个答案:

答案 0 :(得分:1)

CustomTabBarcreateBottomTabNavigator

你的方法是正确的。检查 this Snack 的实现。您将了解如何实现这一目标。

编写以下代码后,只需根据需要更改 Gradient color arrays

您的 BottomTabNavigator 应如下所示....

import * as React from 'react';
import { View } from 'react-native';
import { useTheme } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import CustomTabBar from '../components/CustomTapBar';
import ScreenOne from '../screens/ScreenOne';
import Favourites from '../screens/Favourites';

const Tab = createBottomTabNavigator();

function RootNavigation() {
  const { colors } = useTheme();

  return (
    <View style={{ flex: 1, backgroundColor: colors.background }}>
      <Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />}>
        <Tab.Screen name="ScreenOne" component={ScreenOne} />
        <Tab.Screen name="Favourites" component={Favourites} />
      </Tab.Navigator>
    </View>
  );
}

export default RootNavigation;

您的 CustomTabBar 应如下所示 -

import React, { Component } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';

const FocusedGradient = ['#4c669f', '#3b5998', '#192f6a'];
const NotFocusedGradient = ['#ffffff', '#ffffff'];

function CustomTabBar({ state, descriptors, navigation }) {
  const focusedOptions = descriptors[state.routes[state.index].key].options;

  if (focusedOptions.tabBarVisible === false) {
    return null;
  }

  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const label =
          options.tabBarLabel !== undefined
            ? options.tabBarLabel
            : options.title !== undefined
            ? options.title
            : route.name;

        const isFocused = state.index === index;

        const onPress = () => {
          const event = navigation.emit({
            type: 'tabPress',
            target: route.key,
            canPreventDefault: true,
          });

          if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }
        };

        const onLongPress = () => {
          navigation.emit({
            type: 'tabLongPress',
            target: route.key,
          });
        };

        return (
          <LinearGradient
            colors={isFocused ? FocusedGradient : NotFocusedGradient}
            style={{
              flex: 1,
              backgroundColor: isFocused ? 'dodgerblue' : 'white',
            }}>
            <TouchableOpacity
              accessibilityRole="button"
              accessibilityState={isFocused ? { selected: true } : {}}
              accessibilityLabel={options.tabBarAccessibilityLabel}
              testID={options.tabBarTestID}
              onPress={onPress}
              onLongPress={onLongPress}
              style={{
                minHeight: 50,
                justifyContent: 'center',
                alignItems: 'center',
              }}>
              <Text style={{ color: isFocused ? 'white' : '#222' }}>
                {label}
              </Text>
            </TouchableOpacity>
          </LinearGradient>
        );
      })}
    </View>
  );
}

export default CustomTabBar;

答案 1 :(得分:0)

createBottomTabNavigator 中创建CustomTabBar。按照以下示例使用 expo。 createBottomTabNavigator (CustomTabBar)

enter image description here