如何在React Native中同时启用多个按钮的触摸功能?

10
当我按住一个按钮时,我希望能够同时点击按钮1。
<View>
  
  <View 
  onStartShouldSetResponder={()=>this.console("Button 2 Clicked")}>
    <Text>BUTTON 2</Text>
  </View>
  
  <TouchableOpacity 
  onPressIn={()=>this.console('Button 1 pressed')}
  onPressOut={()=>this.console('Button 1 released')}>
    <View>
      <Text>BUTTON 1</Text>
    </View>
  </TouchableOpacity>

</View>

基本上,我有一个屏幕,在屏幕上通过点击并按住录制按钮(按钮1)可以录制视频。在同一屏幕上,我有一个翻转相机的按钮(按钮2)。我希望我能在录制视频时点击翻转相机按钮。


1
你最终解决了这个问题吗? - Perniferous
4个回答

2

使用View组件的onTouchStart和onTouchEnd属性,可以轻松解决这个问题,而无需使用手势响应器方法。

因此,修改后的代码将如下所示

<View>

  <View onTouchStart={()=>this.console("Button 2 Clicked")}>
    <Text>BUTTON 2</Text>
  </View>

  <View 
    onTouchStart={()=>this.console('Button 1 pressed')}
    onTouchEnd={()=>this.console('Button 1 released')}>
      <Text>BUTTON 1</Text>
  </View>

</View>

2
如果您设置布尔值来处理同时按下两个按钮的多点触控,它将无法正常工作,因为它们会相互抵消,始终保持(真假)或(假真)。我将尝试使用Pan Responder来解决这个问题。https://facebook.github.io/react-native/docs/panresponder.html - Aidan Doherty
2
不幸的是,这似乎只在iOS上有效,而不是Android。 - FOLOF

1

这是我为多个按钮设计的解决方案

import React, { Component } from 'react';
import {
    View,
    PanResponder,
} from 'react-native';
import ReactNativeComponentTree from'react-native/Libraries/Renderer/shims/ReactNativeComponentTree';

export default class MultiTouch extends Component{
    constructor(props) {
        super(props);

        this.onTouchStart = this.onTouchStart.bind(this);
        this.onTouchEnd = this.onTouchEnd.bind(this);
        this.onTouchCancel = this.onTouchCancel.bind(this);

        this.triggerEvent = this.triggerEvent.bind(this);
    }
    onTouchStart(event){
        const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
        this.triggerEvent(element._owner, 'onPressIn');
    }
    onTouchEnd(event){
        const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
        this.triggerEvent(element._owner, 'onPressOut');
    }
    onTouchCancel(event){
        const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
        this.triggerEvent(element._owner, 'onPressOut');
    }
    onTouchMove(event){
       // console.log(event);
    }
    triggerEvent(owner, event){ // Searching down the 
        if(!owner || !owner.hasOwnProperty('_instance')){
            return;
        }
        if(owner._instance.hasOwnProperty(event)){
            owner._instance[event]();
        }else{
            this.triggerEvent(owner._currentElement._owner, event);
        }
    }
    render(){
        return (
            <View
                onTouchStart={this.onTouchStart}
                onTouchEnd={this.onTouchEnd}
                onTouchCancel={this.onTouchCancel}
                onTouchMove={this.onTouchMove}>
                {this.props.children}
            </View>
        );
    }
}

然后,我只需使用该组件将需要同时按下的按钮包装起来。
<MultiTouch style={this.style.view}>
    <UpDownButton />
    <UpDownButton />
</MultiTouch>

干杯!

更新

由于原生react v.0.51中出现了重大更改,我的旧解决方案不再适用。但是我设法创建了一个新的解决方案。不再使用TouchableWithoutFeedback和onPress,而是在每个应该支持多点触控的按钮上使用View和onTouch。

import React, { Component } from 'react';
import {
    View,
} from 'react-native';
export default class RoundButtonPart extends Component{
    constructor(props) {
        super(props);

        this.state = { active: false };

        this.onTouchStart = this.onTouchStart.bind(this);
        this.onTouchEnd = this.onTouchEnd.bind(this);
        this.onTouchCancel = this.onTouchCancel.bind(this);
    }

    onTouchStart(event){
        this.setState({ active: true });
        this.props.onPressIn && this.props.onPressIn();
    }
    onTouchEnd(event){
        this.setState({ active: false });
        this.props.onPressOut && this.props.onPressOut();
    }
    onTouchCancel(event){
        this.setState({ active: false });
        this.props.onPressOut && this.props.onPressOut();
    }
    onTouchMove(event){

    }
    render(){
        return (
            <View
                onTouchStart={this.onTouchStart}
                onTouchEnd={this.onTouchEnd}
                onTouchCancel={this.onTouchCancel}
                onTouchMove={this.onTouchMove}>

                 {this.props.children}
            </View>
        );
    }
}

3
我尝试了一下,在onTouchStart内部,始终记录的是被触摸的第一个按钮。我给每个按钮添加了left和right属性并记录了它们,如果我按住右边的按钮然后轻触左边的按钮,那么始终记录的是right。 - Aidan Doherty

1

尝试:

import { TouchableOpacity } from 'react-native';

改为:

import { TouchableOpacity } from 'react-native-gesture-handler';

我可以帮助您实现多个按钮。

例如,如果在TouchableWithoutFeedback中有一个TouchableOpacity,当触摸TouchableOpacity时,它只会调用TouchableOpacity的onPress,而不会调用TouchableWithoutFeedback的onPress。


0
我使用了react-native-gesture-handler。安装它,然后将 import { TouchableOpacity } from 'react-native'; 替换为 import { TouchableOpacity } from 'react-native-gesture-handler'; 例如:
<View>

  <TouchableOpacity 
  onPressIn={()=>this.console('Button 2 pressed')}
  onPressOut={()=>this.console('Button 2 released')}>
    <View>
      <Text>BUTTON 2</Text>
    </View>
  </TouchableOpacity>

  <TouchableOpacity 
  onPressIn={()=>this.console('Button 1 pressed')}
  onPressOut={()=>this.console('Button 1 released')}>
    <View>
      <Text>BUTTON 1</Text>
    </View>
  </TouchableOpacity>

</View>

链接: https://software-mansion.github.io/react-native-gesture-handler/docs/component-touchables.html

此库还提供了按钮组件,可以直接使用而不必用TouchableOpacity包装文本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接