1

我有一个布局,您可以使用 React Navigation 5 的 createMaterialTopTabNavigator 水平滑动或使用底部的按钮在屏幕之间切换。该按钮出现在每个屏幕上,我想在滑动动作期间将其隐藏,并在滑动停止时重新出现。

有谁知道这是否可能?

const Introduction1 = () => {
    return (
        <View style={styles.container}>
            <Text style={{ ...globalStyles.hTitle, ...globalStyles.h1 }}>Welcome</Text>
            <Text style={globalStyles.text}>
                Before you start there is a short introduction available.
            </Text>
            <Text style={{ ...globalStyles.text, ...globalStyles.bold }}>Do you want to see it?</Text>

            <BottomButtons name="Continue" destination="Introduction2" />
        </View>
    );
function SwiperNav() {
    return (
        <Swipe.Navigator
            tabBarOptions={{
                style: {
                    display: 'none'
                }
            }}>
            <Swipe.Screen name="Introduction1" component={Introduction1} />
            <Swipe.Screen name="Introduction2" component={Introduction2} />
            <Swipe.Screen name="Introduction3" component={Introduction3} />
            <Swipe.Screen name="Introduction4" component={Introduction4} />
            <Swipe.Screen name="Introduction5" component={Introduction5} />
        </Swipe.Navigator>
    );
}

在此处输入图像描述 在此处输入图像描述

4

1 回答 1

1

原始答案

我推荐一种不同的方法。滑动时隐藏元素很困难(根据我自己的经验),根据反应导航文档不推荐:

一些选项卡导航器(例如底部选项卡导航器)也有一个 tabBarVisible 选项,可用于根据屏幕选项分辨率指南中的说明隐藏选项卡栏。但是,我们不建议使用它,因为在导航中显示/隐藏标签栏会影响堆栈导航器的动画,从而导致故障行为。

我的方法是在导航器之外定义继续按钮。

首先在您的目录根目录下创建一个RootNavigation文件,如下所示。

import * as React from 'react';

export const navigationRef = React.createRef();

export function getCurrentRouteName() {
  return navigationRef.current?.getCurrentRoute().name;
}

export function navigate(name, params) {
  navigationRef.current?.navigate(name, params);
}

这个RootNavigation文件的想法是访问navigation道具并从我们的按钮中获取当前路线名称。如果按钮放置在导航器之外,则这是不可能的。

将 navigationRef 传递给您的NavigationContainer.

import * as RootNavigation from './RootNavigation';
// ...
const App = () => {
  return (
    <NavigationContainer ref={RootNavigation.navigationRef}>
      <SwiperNav />
      <BottomButtons name="Continue" />
    </NavigationContainer>
  );
}

以下函数用于根据当前路线名称确定继续按钮应转到的下一条路线。constants如果您愿意,您可以使用或enums用于路由名称来清理代码。

const getSwipeNavigatorNextDestination = currentRouteName => {
  switch (currentRouteName) {
    case 'Introduction1':
      return 'Introduction2';
      break;
    case 'Introduction2':
      return 'Introduction3';
      break;
    // etc...
  }
};

我不知道你的BottomButtons组件到底是什么样子,但重要的是你定义了一个函数来处理onPress你在哪里检索下一个目的地并使用RootNavigation.

const BottomButtons = ({name}) => {
  const handleBtnNavigate = () => {
    const nextDestination = getSwipeNavigatorNextDestination(
      RootNavigation.getCurrentRouteName(),
    );
    RootNavigation.navigate(nextDestination)
  };
  return <Button title={name} onPress={() => handleBtnNavigate()} />;
};

如果你想了解更多关于 RootNavigation 的想法,你可以参考文档:https ://reactnavigation.org/docs/navigating-without-navigation-prop/ 。

如果有什么不清楚的可以评论,我可以澄清。

对原始答案的扩展

您应该在您的应用程序中只使用一个 NavigationContainer。如果您想在导航到不属于介绍性屏幕的屏幕后隐藏继续按钮,我建议更改以下内容:

const App = () => {
  const [isShowingIntroduction, setIsShowingIntroduction] = useState(true);

  return (
    <NavigationContainer ref={RootNavigation.navigationRef}>
      <SwiperNav />
      {isShowingIntroduction && (
        <BottomButtons
          name="Continue"
          setIsShowingIntroduction={setIsShowingIntroduction}
        />
      )}
    </NavigationContainer>
  );
};

有条件地显示继续按钮。

const BottomButtons = ({name, setIsShowingIntroduction}) => {
  const handleBtnNavigate = () => {
    const nextDestination = getSwipeNavigatorNextDestination(
      RootNavigation.getCurrentRouteName(),
    );
    if (nextDestination == 'ScreenNotPartOfIntroduction') {
      setIsShowingIntroduction(false);
    }
    RootNavigation.navigate(nextDestination);
  };
  return <Button title={name} onPress={() => handleBtnNavigate()} />;
};

我在这里所做的是在应用程序组件(继续按钮的父组件)中创建一个状态变量和随附的设置器。这允许我们将 setter 函数传递给继续按钮。然后在按钮组件内部,我们可以创建一个检查:如果nextDestination屏幕名称不属于介绍屏幕名称集的一部分,则调用setIsShowingIntroduction(false). 应用程序组件更新并隐藏它导航到的按钮nextDestination

于 2020-07-11T13:16:59.763 回答