React-native-gesture-handler: 不适用于模态

创建于 2018-04-11  ·  71评论  ·  资料来源: software-mansion/react-native-gesture-handler

嗨!
我在Android上有一个小问题,当GestureHandler组件位于Android上的模式时,不会触发onGestureEvent 。 当我将模式更改为视图时,它可以正常工作👌

在iOS上没问题

Android Bug Can repro Important

最有用的评论

在模态中解决这个问题的小技巧:

import { TouchableWithoutFeedback } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
<TouchableWithoutFeedback onPress={...}
    <RectButton>
         ...
    </RectButton>
</TouchableWithoutFeedback>

所有71条评论

+1
任何解决方法?

我暂时不使用Modal,只是在绝对位置使用View重新创建

在谷歌搜索和聊天之后,现在使用模态屏幕

+1

@martinezguillaume@mordaha ,@csto
我确实看过这个问题,我想这不是我们图书馆的问题,而是RN Core。

@osdnk是可修复的吗?

+1手势不适用于模式

我今天也遇到了这个错误。

同样的问题。 手势不适用于Android上的模式。
以世博为例

我也是。 在模式上测试了react-native的PanResponder处理程序-正常工作。

我对此有一个想法:当我们将此库链接到android项目时,我们正在做下一步

<strong i="7">@Override</strong>
            protected ReactRootView createRootView() {
                return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }

而且我们知道模态是独立的程序包。 可能有相同的想法吗?

我使用的是标准React Native Modal并且遇到了这个问题。
我通过创建一个新屏幕并将其显示为模式来解决该问题。 我正在使用react-native-navigation ,所以:

Navigation.showModal({
    component: {
      name: navRoutes.ImageModal,
      passProps: { image },
    },
  })

手势在iOS和Android上均能正常工作,但我仍然可以从原始模式中获得想要的透明背景。

我已经钻了一段时间了。

  1. 这是RNGH的问题。 对不起😒
  2. 碰巧在RN根视图下未渲染bc模态。
  3. 通过使用与RNRootView相似的方式替换模态的机制(通过使用一些额外的逻辑将其包装)可以解决此问题。 参见https://github.com/kmagiera/react-native-gesture-handler/blob/master/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootViewManager.java
  4. 我现在没有时间这样做,这是一项耗时的工作,可能需要在Android本机端的RNGH内核中复制一些代码。

如果有人想要并且有时间去做,我会很乐意地对其进行审查,如果它可行且不太笨拙,请立即合并。

@martinezguillaume @mordaha @csto @ mars-lan @ParhamZare @ewendel @ Via-profit @Dmitrylolo @LaVielle

另外,我在两个月前做了尝试。

https://github.com/kmagiera/react-native-gesture-handler/commit/139da18039683bed3c439c991c7eaf802086bf86

也许对某人来说可能是一个灵感🤷‍♂️

@osdnk我的应用程序需要此功能,因此我想尝试一下,但是我对RNGestureHandler或Android的使用经验不足。 您能否给我一些更多的见解,以使我能够使其正常工作?
另外,我正在查看您以前的尝试,我想知道完成它所缺少的内容,以及它是否可以用作起点。

同样的错误。

@kmagiera @osdnk对此有任何更新吗?
甚至Touchable*都不能在模态中使用,这令人沮丧

+1。 我使用带有模式的reanimated-bottom-sheet

任何更新? 也许,还有其他不受此问题困扰的模态组件吗? RN的模式诚实地工作得很糟糕,并且充满了错误(例如,与警报结合在一起会卡住)

奇。 该组件应该在内部使用react的模式。 做到了
对您有所帮助?

El jue。,2019年5月30日14:38,Mars Lan [email protected]
escribió:

@cristianoccazinsp https://github.com/cristianoccazinsp我结束了
使用https://github.com/react-native-community/react-native-modal

-
您收到此邮件是因为有人提到您。
直接回复此电子邮件,在GitHub上查看
https://github.com/kmagiera/react-native-gesture-handler/issues/139吗
或使线程静音
https://github.com/notifications/unsubscribe-auth/ALU263GRH2KHBXUZBGHNKA3PYAGJTANCNFSM4EZ6UZLQ

@cristianoccazinsp它仅使用RN的模式来覆盖屏幕,可以通过将coverScreenfalse来禁用它

@cristianoccazinsp它仅使用RN的模式来覆盖屏幕,可以通过将coverScreenfalse来禁用它

但是,有没有一种方法可以使用此道具显示全屏模式,而该道具未在应用程序的根组件中呈现?

@jvaclavik我将它与https://github.com/callstack/react-native-paper结合使用,该组件具有一个专门用于此目的的名为Portal的组件。

这可能无法解决所有用例,但是在将prop propagateSwipe为true时,您可以在本机模式中启用手势。

这个问题似乎与https://github.com/kmagiera/react-native-screens/issues/61有关

不要在Android中使用React本机屏幕。 经过测试并可以正常使用“复活的底页”

如果(Platform.OS ==='ios'){
useScreens();
}

这个用于透明bg的React Navigation Modal配置是

ScreenOne:{
屏幕:ScreenOne,
navigationOptions:{
posesEnabled:否
},
}
{
模式:“模式”,
transparentCard:true,
headerMode:“无”,
cardStyle:{
backgroundColor:“透明”,
不透明度:1
},
transitionConfig:()=>({
containerStyle:{
backgroundColor:“透明”,
}
})
}

@osdnk固定了吗?

这个太痛苦了。
在解决Google问题之前,我花了一些时间,竭尽全力试图弄清楚为什么相同的组件在iOS和Android上都可以运行,但只能在应用程序内的某些位置上运行

我们有同样的问题-它不适用于模式。
我想知道是否有人正在对此进行工作或知道任何状态更新?
我们是否需要删除该库并切换到RN平移处理程序?
有什么建议吗?

同样在这里。 RectButton在https://github.com/react-native-community/react-native-modal内部不起作用

@deflorilemarului @ kesha-antonov @fauker
既不会浪费您一些时间,也不会浪费Modal或基于Modal的软件包(如果它们不需要您链接本机依赖项-它们基于react-nativeModal )将为您提供帮助(基本上,我已经尝试了所有方法)。
在Android的<Modal>...</Modal>内渲染时,所有与gesture-相关的组件(对我们而言是bottomsheet-behaviour)都不会注册任何触摸/滑动等。
我可以想到3种解决方案:

  1. 如果使用模态,则使用任何其他库。 您可能需要将一些基于滑动的组件重写为PanResponder ; 这很痛苦,但是很简单;
  2. 使用为portals模态。 它们实际上不是门户,也不是模态门户-React-native不支持门户,因为存在单个应用程序主机-但是它们的工作方式是将主机组件放在应用程序的某个位置,并在应用程序堆栈上方的绝对视图中呈现模式内容; 这是一个可行的解决方案,但是由于子级在上下文提供者之上呈现,因此您将丢失任何useContext()调用; 对我们不起作用,因为navigation上下文丢失了;
  3. 使用导航库提供的模式( react-navigation ); 这是可行的,但是API并不是很好-对于一个屏幕,您不能将单个屏幕作为模态,只能将一个堆栈置于模态模式; 这是我坚持的解决方案。

好了,有最后的解决方案-修补本机android实现(如果您使用的是expo,则不可能)或等待库中的修补程序,然后等到合并到expo中。

ps
不要误会我的意思,这个库太棒了,我无法承受太多的工作投入,以及最终用户的体验要好得多,但是像这样的错误使我想尽全力。

很少有库需要我们处理本机上下文,如果这样的话:

对于android,我们将需要RNGH文档中所述的特殊注意事项

更新您的MainActivity.java文件
Screen Shot 2019-11-30 at 12 17 07 PM

希望能帮助到你

很少有库需要我们处理本机上下文,如果这样的话:

对于android,我们将需要RNGH文档中所述的特殊注意事项

更新您的MainActivity.java文件
Screen Shot 2019-11-30 at 12 17 07 PM

希望能帮助到你

是的,这对我来说非常有效。 寻找使我的Android应用程序可滑动的解决方案时,我几乎感到沮丧。

还是行不通
如果更改模式以查看一切正常...

@romanonthego

好了,有最后的解决方案-修补本机android实现(如果您使用的是expo,则不可能)或等待库中的修补程序,然后等到合并到expo中。

您能告诉我在本机android代码中打补丁的内容吗?

@osdnk令人兴奋。 它也可以与DialogFragment吗?

在尝试#937之后,我发现它对我不起作用...

也许是因为我正在使用wix的react-native-navigation? 据我所知,每个屏幕都已注册了gestureHandlerRootHOC(该库与常规,非模态视图完美兼容)。

这是我在Modal中尝试过RectButton的屏幕的一部分(基本上与文档更新中的一样)

  renderSearchScreen = () => {
    const { showSearchHistory } = this.state;
    const ExampleWithHoc = gestureHandlerRootHOC(() => {
      return (
        <View style={genericStyles.container}>
          <SearchScreen
            searchBar={{
              ...this.searchBar,
              searchQuery: this.props.searchQuery,
            }}
            onBackPress={() => {
              this.setState({ showSearchHistory: false });
            }}
          />
        </View>
      );
    });

    if (showSearchHistory) {
      return (
        <RNModal
          animationType="fade"
          transparent
          visible={this.state.showSearchHistory}
          onRequestClose={() => {}}>
          <ExampleWithHoc />
        </RNModal>
      );
    }

    return null;
  };

模态应该在预期的时候加载,但是RectButton不会触发onPress事件。 我试图用一个全新的应用程序制作一个最小的可重复演示,但是后来我遇到了#848#676#835(可能是彼此的重复)。

高达#937

太棒了! 不过,对于我来说,它仍然无法与react-native-modal使用!

_ //编辑:实际上,默认模式也不起作用,但是如果我没记错的话,它应该

我玩了一段时间,才发现问题所在。 但是,我不确定是什么原因导致的,以及如何修复它。

在我的情况的问题是,我react-native-gesture-handler将里面没有工作@react-navigation/stack ,如果放在一个模式里面(所以基本上Stack.Navigator > SomeScreenComponent > Modal > gestureHandlerRootHOC(PanGestureHandler)失败)。

如果我剪掉Stack Navigator或改用Tab Navigator,它的工作原理就像是一个超级按钮,因此我很确定这是Stack Navigators的错。

相关软件包版本:

[email protected]
@react-navigation/[email protected]
@react-navigation/[email protected]

我将尝试尽快设置一个演示仓库,让我知道是否可以提供更多有用的信息。

这是一个演示应用程序( npx react-native init几乎为空白),它将显示问题。 您可以在应用程序内切换堆栈导航器,并查看PanGestureHandler如何起作用和不起作用。

https://github.com/mxmzb/react-native-breakable-app

我有一个类似的问题。 似乎Stack.Navigator在Android上无法正常运行。 我使用mode =“ modal”还是“ card”都没关系。

所以我在玩,有以下代码

import { SafeAreaView, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack'

import { enableScreens } from 'react-native-screens';
enableScreens(); // <-- this fucked it up

const Screen1 = ({ navigation }) => {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button title="Open Modal" onPress={() => navigation.push('Modal')} />
      </SafeAreaView>
    )
  }

  const Screen2 = ({ navigation }) => {
    return (
      <SafeAreaView style={{ flex: 1 }}>
        <Button title="Close Modal" onPress={() => navigation.goBack()} />
      </SafeAreaView>
    )
  }

const App = () => {

return (
        <NavigationContainer>
          <Stack.Navigator headerMode="none">
            <Stack.Screen name="Main" component={Screen1} />
            <Stack.Screen name="Modal" component={Screen2} />
          </Stack.Navigator>
        </NavigationContainer>
  )

}

然后我删除了这一行;
enableScreens();

然后它可以在Android上正常工作。

在模态中解决这个问题的小技巧:

import { TouchableWithoutFeedback } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
<TouchableWithoutFeedback onPress={...}
    <RectButton>
         ...
    </RectButton>
</TouchableWithoutFeedback>

我有类似的问题。 有什么解决方法吗?

我试图在模态中使用https://github.com/osdnk/react-native-reanimated-bottom-sheet ,这是不可能的,我终于用react-navigation屏幕动画解决了:

https://github.com/osdnk/react-native-reanimated-bottom-sheet/issues/143#issuecomment -614300015

在模态中解决这个问题的小技巧:

import { TouchableWithoutFeedback } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
<TouchableWithoutFeedback onPress={...}
    <RectButton>
         ...
    </RectButton>
</TouchableWithoutFeedback>

@gideaoms 。 我不知道您的评论在这里是如何被忽视的。 它绝对可以解决问题。 谢啦!

这是一个演示应用程序( npx react-native init几乎为空白),它将显示问题。 您可以在应用程序内切换堆栈导航器,并查看PanGestureHandler如何起作用和不起作用。

https://github.com/mxmzb/react-native-breakable-app

那么,解决方案是什么?

我仍然有同样的问题。
有什么解决办法吗?

这在1.6.0上仍然是个问题

尝试了上述所有建议,但仍然没有运气。 请帮助它确实令人沮丧。
我在0.62.2中的react native版本尝试与/ react-native-gesture-handler 1.5.6和1.6.0一起使用。

仍然是^1.7.0

仍然无法正常工作:-1:

我们使用wix-navigation。 也许相关的东西?

好吧,我发现了一个可能的解决方法,它完全可以满足我们的要求,并且可以在iOS和Android上正常工作。

https://www.youtube.com/watch?v=tLQjGHDiRkM

@steniowagner就像自定义模式吗? 我不推荐
只需使用react-navigation或native-stack modal,它就可以正常工作。

嗯,没有对反应导航进行测试(对于我的情况来说听起来太高了),但是也许这是目前最好的方法。

谢谢@ a-eid!

根据文档
https://docs.swmansion.com/react-native-gesture-handler/docs/#usage -with-modals-on-android

但仍然对我不起作用。

@gideaoms技巧可能适用于按钮,但我的用例是在模式中使用PinchGestureHandler

在模态中解决这个问题的小技巧:

import { TouchableWithoutFeedback } from 'react-native';
import { RectButton } from 'react-native-gesture-handler';
<TouchableWithoutFeedback onPress={...}
    <RectButton>
         ...
    </RectButton>
</TouchableWithoutFeedback>

这个问题已存在2年多了,有没有解决的计划?

我已经为我的应用创建了自定义Slider组件,并且在Android上根本无法使用它们,因为我的应用中很多视图都是Modals

我已经将每个屏幕和Modal组件包装在gestureHandlerRootHoC (使用wix / react-native-navigation)

我尝试用gestureHandlerRootHoc包装屏幕和组件,但均未成功。 我没有尝试RectButton方法,因为我需要一个PanGestureHandler来实现模态上从下到下的消除行为。 令人沮丧的是,由于它在iOS上完美运行,并且由于我使用的是react-native-modal ,它实际上是开箱即用即可滑动清除的,所以我什至尝试使用该方法只要您在模式中没有可滚动的内容,它就可以工作,因为那样在iOS和Android上都存在问题,所以我有点卡住了...

总结一下:

  1. ❌RNGH不会在工作react-native<Modal>组分(即使在组件包装在gestureHandlerRootHOC
  2. ✅RNGH确实在wix/react-native-navigation的屏幕中工作,该屏幕使用Navigation.showModal (即使屏幕包裹在gestureHandlerRootHOC
  3. if如果使用react-navigation的push函数和modal: true显示RNGH显然可以工作,但是仅当不使用本机堆栈( enableScreens() / createNativeStackNavigator() )时才可以使用。

如果需要,我可以提供更多详细信息。

react-native-modal-animated可与react-native-gesture-handler一起使用,因为react-native-modal-animated仅使用视图即可创建模态。

@flysky为什么为什么如果react-native-modal-animated不使用像react-native-modal这样的单独活动,那么它将如何呈现在所有内容之上? 如果使用绝对位置,则在某些情况下可能会出现问题。

@ waheedakhtar694 ,它使用的是绝对值。 至少在我看来,没有问题:stuck_out_tongue_closed_eyes:

@jvaclavik我将它与https://github.com/callstack/react-native-paper结合使用,该组件具有一个专门用于此目的的名为Portal的组件。

@jvaclavik所述,使用react-native-paper中的Portal解决。
我用PaperProvider包装了我的应用程序,然后将handleHandlerRootHOCPortal对其进行了包装
现在底表可以在Android works上使用

_EDIT:出于某种原因,平移手势有效,但onPress事件不起作用(但显示了波纹)...
编辑2:这是我使用的库的问题,我解决了将可触摸导入从“ react-native”更改为“ react-native-gesture-handler”的问题。

这是您可以尝试的一些代码

/*
 App.js:
 - import { Provider as PaperProvider } from "react-native-paper";
 - wrap your App with PaperProvider
*/

// ModalFixed.js
import { Portal } from 'react-native-paper';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';

const ModalFixed = (props) => {
  <View style={styles.modal}>
    <View style={styles.shadow} />
    {/* MODAL CONTENT HERE, you can put props.children to reuse this component */}
  </View>
}

const styles = StyleSheet.create({
  modal: {
    width: "100%",
    height: "100%"
  },
  shadow: {
    position: "absolute",
    width: "100%",
    height: "100%",
    backgroundColor: "rgba(0,0,0,0.3)",
  }
})

const _ModalFixed = gestureHandlerRootHOC(SheetPopup)
export default (props) => {
  return (
    <Portal>
      <_ModalFixed {...props} />
    </Portal>
  )
}

它为我工作:
<TouchableWithoutFeedback onPress={() => { console.log("press"); }} > <Text> <RectButton> ... </RectButton> </Text> </TouchableWithoutFeedback>

这事有进一步更新吗? 我们有两个项目,iOS能够按预期工作,但Android模式却令人头疼。 我们宁愿不必从项目中删除模态……这是一项重大的设计改革。 :/

@DavidAPears您是否尝试过将模态包装在gestureHandlerRootHOC

这样的事情?


const ModalInner = gestureHandlerRootHOC(function GestureExample() {
  return (
    <View>
      { RNGH components . }
    </View>
  );
});

export default function ModalForX() {
  return (
    <Modal animationType="slide" transparent={false}>
      <ModalInner />
    </Modal>
  );
}


react-native-portalizegestureHandlerRootHOCPortal组合对我有用。 像这样:

<Portal>
   <Modal>
      <GestureHandlerRootHOCWrappedComponent />
   </Modal>
</Portal>

在模态作品上设置coverSreen = {false}。 但是需要我的模态覆盖屏幕

从'react-native'导入{Platform,Modal};
从'react-native-gesture-handler'导入{gestureHandlerRootHOC};
从'../AnimatedBottomSheet'导入{AnimatedBottomSheet};

const AnimatedBottomSheetWrapper = Platform.OS ==='android'吗? poseHandlerRootHOC(AnimatedBottomSheet):AnimatedBottomSheet;

不知道这是否对某人有帮助,我在将这个库与react-native-modal一起使用时也遇到了问题,但是除了包装modal handlerHandlerRootHOC的子元素(这对于按钮工作正常外,但是在modal + voidKeyboard中输入文本时遇到了问题= true,每按一次键,键盘就会关闭)所以,我唯一要做的就是将其用作模态儿童包装,如下所示:

import Modal from 'react-native-modal';
import { gestureHandlerRootHOC } from 'react-native-gesture-handler';

const GestureHandlerWrapper = gestureHandlerRootHOC(
  ({ children }) => <View>{children}</View>,
  { flex: 0 }
);

export const CustomModal: React.FC<Props> = ({
  children,
...rest
}) => {
  return (
    <Modal
      {...rest}
    >
      <GestureHandlerWrapper>    
          {children} 
      </GestureHandlerWrapper>
    </Modal>
  );
};
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

tallen11 picture tallen11  ·  3评论

brentvatne picture brentvatne  ·  5评论

nguyenhose picture nguyenhose  ·  4评论

enahum picture enahum  ·  4评论

chrisdrackett picture chrisdrackett  ·  4评论