我正在尝试使用tabBarComponent
中的createMaterialTopTabNavigator
为我的React Native应用使用自定义组件("react-native-tabs"
属性),该组件是{{1}中的BottomNavigation
}}。
我已经从https://github.com/react-navigation/material-bottom-tabs复制了几乎所有代码,因为这是我发现使用"react-native-paper"
作为自定义组件的唯一来源
我有3条主要代码:
BottomNavigation
TabNavigator (component)
class CustomTabNavigator extends React.Component {
_getColor = ({ route }) => {
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const options = descriptor.options;
if (this.context === 'dark' && options.tabBarColorDark) {
return options.tabBarColorDark;
} else if (options.tabBarColorLight) {
return options.tabBarColorLight;
} else {
return options.tabBarColor;
}
};
_getactiveColor = () => {
let { activeColor, activeColorLight, activeColorDark } = this.props;
if (this.context === 'dark' && activeColorDark) {
return activeColorDark;
} else if (activeColorLight) {
return activeColorLight;
} else {
return activeColor;
}
};
_getInactiveColor = () => {
let { inactiveColor, inactiveColorLight, inactiveColorDark } = this.props;
if (this.context === 'dark' && inactiveColorDark) {
return inactiveColorDark;
} else if (inactiveColorLight) {
return inactiveColorLight;
} else {
return inactiveColor;
}
};
_getBarStyle = () => {
let { barStyle, barStyleLight, barStyleDark } = this.props;
return [barStyle, this.context === 'dark' ? barStyleDark : barStyleLight];
};
_isVisible() {
const { navigation, descriptors } = this.props;
const { state } = navigation;
const route = state.routes[state.index];
const options = descriptors[route.key].options;
return options.tabBarVisible;
}
_renderIcon = ({
route,
focused,
color,
}) => {
return this.props.renderIcon({ route, focused, tintColor: color });
};
render() {
const {
navigation,
descriptors,
...rest
} = this.props;
const activeColor = this._getactiveColor();
const inactiveColor = this._getInactiveColor();
const barStyle = this._getBarStyle();
const isVisible = this._isVisible();
const extraStyle =
isVisible === false
? {
display: 'none',
position: undefined,
}
: null;
return (
<BottomNavigation
{...rest}
activeColor={activeColor}
inactiveColor={inactiveColor}
renderIcon={this._renderIcon}
barStyle={[barStyle, extraStyle]}
navigationState={navigation.state}
getColor={this._getColor}
/>
)
}
}
TabNavigation (navigator)
class CustomTabNavigation extends React.Component {
_renderScene = ({ route }) => {
const { screenProps, descriptors } = this.props;
const descriptor = descriptors[route.key];
const TabComponent = descriptor.getComponent();
return (
<SceneView
screenProps={screenProps}
navigation={descriptor.navigation}
component={TabComponent}
/>
);
};
_renderIcon = ({
route,
focused,
tintColor,
horizontal = false,
}) => {
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const options = descriptor.options;
if (options.tabBarIcon) {
return typeof options.tabBarIcon === 'function'
? options.tabBarIcon({ focused, tintColor, horizontal })
: options.tabBarIcon;
}
return null;
};
_getLabelText = ({ route }) => {
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const options = descriptor.options;
if (options.tabBarLabel) {
return options.tabBarLabel;
}
if (typeof options.title === 'string') {
return options.title;
}
return route.routeName;
};
_getAccessibilityLabel = ({ route }) => {
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const options = descriptor.options;
if (typeof options.tabBarAccessibilityLabel !== 'undefined') {
return options.tabBarAccessibilityLabel;
}
const label = this._getLabelText({ route });
if (typeof label === 'string') {
const { routes } = this.props.navigation.state;
return `${label}, tab, ${routes.indexOf(route) + 1} of ${
routes.length
}`;
}
return undefined;
};
_getTestID = ({ route }) => {
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const options = descriptor.options;
return options.tabBarTestID;
};
_getBadge = ({ route }) => {
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const options = descriptor.options;
return options.tabBarBadge;
};
_makeDefaultHandler = ({
route,
navigation,
}) => () => {
if (navigation.isFocused()) {
if (route.hasOwnProperty('index') && route.index > 0) {
navigation.dispatch(StackActions.popToTop({ key: route.key }));
} else {
navigation.emit('refocus');
}
} else {
this._jumpTo(route.routeName);
}
};
_handleTabPress = ({ route }) => {
this._isTabPress = true;
Promise.resolve().then(() => (this._isTabPress = false));
const { descriptors } = this.props;
const descriptor = descriptors[route.key];
const { navigation, options } = descriptor;
const defaultHandler = this._makeDefaultHandler({ route, navigation });
if (options.tabBarOnPress) {
options.tabBarOnPress({ navigation, defaultHandler });
} else {
defaultHandler();
}
};
_handleIndexChange = index => {
if (this._isTabPress) {
this._isTabPress = false;
return;
}
this._jumpTo(this.props.navigation.state.routes[index].routeName);
};
_jumpTo = routeName => {
const { navigation } = this.props;
navigation.dispatch(
SwitchActions.jumpTo({
routeName,
key: navigation.state.key,
})
);
};
_isTabPress = false;
render() {
const {
descriptors,
navigation,
screenProps,
navigationConfig,
} = this.props;
const { state } = navigation;
const route = state.routes[state.index];
const descriptor = descriptors[route.key];
const options = {
...navigationConfig,
...descriptor.options,
};
return (
<CustomTabNavigator
{...options}
getLabelText={this._getLabelText}
getAccessibilityLabel={this._getAccessibilityLabel}
getTestID={this._getTestID}
getBadge={this._getBadge}
renderIcon={this._renderIcon}
renderScene={this._renderScene}
onIndexChange={this._handleIndexChange}
onTabPress={this._handleTabPress}
navigation={navigation}
descriptors={descriptors}
screenProps={screenProps}
/>
);
}
}
Main navigation
我希望能够使用“反应导航”中的const TabNavigator = createStackNavigator(
{
TabsStack: {
...,
{
...,
tabBarComponent: ({ props }) => <CustomTabNavigation {...props} />
})
},
}
);
中的swipeEnabled
功能(到每个屏幕的动画过渡),以及一个外观更好的标签栏,但它表示createMaterialTopTabNavigator
的渲染功能中的'navigation.state is undefined'
(第CustomTabNavigation
行),但我看不到原因。
答案 0 :(得分:0)
我认为这里存在错误:tabBarComponent: ({ props }) => <CustomTabNavigation {...props} />
应该是tabBarComponent : props => <CustomTabNavigation {...props} />
或仅仅是tabBarComponent: CustomTabNavigation
BottomNavigation
不是标签栏组件,而是完整的标签导航组件。您可以通过不渲染内容来像标签栏一样使用它。
但是请考虑,无论是Android还是iOS设计准则都没有在底部选项卡中添加滑动手势,因此UX会不一致。通常,顶部标签栏具有滑动手势,因为用手指更难到达顶部栏。