【问题标题】:Create a hole in react-native webview for touch events在 react-native webview 中为触摸事件创建一个洞
【发布时间】:2018-01-15 18:54:19
【问题描述】:

我们正在尝试重复与此插件相同的操作:https://github.com/mapsplugin/cordova-plugin-googlemaps/blob/master/README.md(此插件如何工作)但使用 react-native + mapbox gl(native)。

这个想法很简单:webview 和 mapview 是“兄弟”,webview 在 mapview 之上,webview 的一部分是透明的,mapview 显示在它下面。我们希望这个透明区域中发生的任何触摸事件都不会被 webview 和气泡/mapview 捕获,以便您可以触摸/拖动/缩放地图。

简单地说:我们希望 webview 的部分(不是全部)不捕获事件,而是允许底层视图捕获它们。

看起来 react native 中有一些方法允许这样做(条件控制事件捕获)(https://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture),但我们找不到任何工作示例来测试它,我们无法完全理解文档提供了(我们甚至无法理解应该为父视图或子视图指定此回调)。

所以基本上我们只需要一些 react-native 的工具来有条件地捕获触摸事件。

谁能帮助我们解决这个问题?地图/webview 的示例可能太复杂了,在两个视图中对事件进行条件捕获应该会有很大帮助。

【问题讨论】:

  • 您找到(完整)解决方案了吗?

标签: react-native event-capturing


【解决方案1】:

我不确定这是否是完美的解决方案,但您可以做的是创建一个 EvenEmitter 并让 Webview 捕获所有点击。应该由地图处理的,我可以发送到地图本身。

我在屏幕上使用它们,可能会创建多个组件,但可以将它们发送到父屏幕。它主要用于处理模态屏幕。

import EventEmitter from 'react-native/Libraries/vendor/emitter/EventEmitter';

this._eventEmitter = new EventEmitter();

        this._eventEmitter.addListener('modal', (data) => {
            this.setState({
                visibleModal: true,
                modalData: data
            });
        });

然后你可以像使用emitter.emit("modal", data)

编辑:

这是另一种方法,它还向您展示了如何使用您在问题中提出的方法。

class Class extends Component {

    onStartShouldSetResponder = () => true;
    onEvent = (e) => {
        let object = {};
        object.locationX = e.nativeEvent.locationX;
        object.locationY = e.nativeEvent.locationY;
        object.pageY = e.nativeEvent.pageY;
        object.pageX = e.nativeEvent.pageX;
        object.target = e.nativeEvent.target;
        //object.touches = e.nativeEvent.touches; //These will trigger a cyclic error while parsing but you can access them
        //object.changedTouches = e.nativeEvent.changedTouches;
        object.identifier = e.nativeEvent.identifier;
        alert(JSON.stringify(object));

        if (object.pageX > this.state.x && object.pageX < (this.state.x + this.state.width) && object.pageY > this.state.y && object.pageY < (this.state.y + this.state.height))
            alert("inside") //Here you can trigger whatever function you need from the underlying view
    }

    onLayout = (event) => {
        this.setState({
            x: event.nativeEvent.layout.x,
            y: event.nativeEvent.layout.y,
            width: event.nativeEvent.layout.width,
            height: event.nativeEvent.layout.height,
        });
    }

    render(){

        return(    

            <ScrollView>

            <View ref={"target"} style={{
                position: 'absolute',
                height: 200,
                width: 200,
                left: 100,
                top: 100,
                backgroundColor: 'rgba(0,0,0,0.5)'
            }}
            onLayout={this.onLayout}
            />

            <View 
            onl
            onStartShouldSetResponder={this.onStartShouldSetResponder} 
            onResponderMove={this.onEvent}
            style={{
                backgroundColor: 'rgba(255,0,0,0.3)',
                width: '100%',
                height: 150
            }}/>

            <TouchableWithoutFeedback 
            onPress={this.onEvent}
            onLongPress={this.onEvent}
            style={{
                backgroundColor: 'rgba(0,255,0,0.3)',
                width: '100%',
                height: 150
            }}> 
            <View style={{height: 150, backgroundColor: 'rgba(0,255,0,0.3)'}}/>
            </TouchableWithoutFeedback>

            <View 
            onTouchStart={this.onEvent}
            onTouchEnd={this.onEvent}
            style={{
                backgroundColor: 'rgba(0,0,255,0.3)',
                width: '100%',
                height: 150
            }}> 
            </View>

            </ScrollView>

        );
    }

}

也许这会帮助您将事件传递给其他视图

【讨论】:

  • 感谢您的回答!我也在玩这个想法,但似乎找不到任何合适的库,不仅可以正确传递事件本身,还可以正确传递所有正确的元数据:点击坐标等。地图还有一些“复杂”事件,如“捏缩放”等,我担心手动发出这个“手势”。你能推荐一些可以做到的反应库吗?
  • 您的设置实际上可能变得非常复杂。你能描述一下你的用例吗?我的意思是,您可以使用 react-native-maps 中的地图组件并对其进行扩展,或者您可以在地图上方拥有一个绝对位置且宽度和高度较小的 web 视图等。
  • 最近我们用Cordova做了一个房地产申请。它相当大,有很多不同的组件,有两个主要部分:客户列表搜索和客户支持(建议、分析等)。它在 iOS 平台(iphone6 和更高版本)和新的 Android 设备上运行良好,但旧的 android 设备的处理器和 WebGL 支持较差。所以现在我们正在考虑将我们拥有的一些组件(地图、列表等)移动到本机元素,同时将所有其他(很多!)组件保留在 WebView 中。现在,当然,我们可以将一些路由完全移动到 Native...>next
  • 但遗憾的是,这些路线上有很多“模态”(完整列表模态、过滤器等),并且需要大量工作才能将这些路线完全迁移到 Native。所以我们想要做这种混合 - 我们知道屏幕上应该显示原生组件的确切“矩形”(坐标),并希望它们在我们的 WebView 下显示它,以保持打开不同模式和准备好的动画的能力“在上面”。
  • 嗯,我相信您应该从按屏幕迁移开始。有一个很好的包,它是由 AirBnb 制作的 react-native-maps,您可以使用自定义标注或指针,因此您可以在那里捕捉一些触摸事件。至于模态,也许你实际上有一个 RN 模态,它基本上是一个 webview,你可以在其中加载现有的模态。在我看来,最好从头开始迁移所有内容。我确实有一个组件,例如它上面有视图,地图回答通常的触摸事件,然后框解决其余的问题。它只是基本上......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多