React Native中pointerEvent属性

96
于连林520wcf
2016.08.10 14:11* 字数 589

在React Native界面开发中, 如果使用绝对定位布局,在代码运行时的某个时刻有可能会遮盖住它的下方的某个组件。这是因为绝对定位只是说这个组件的位置由它父组件的边框决定。
绝对定位的组件可以被认为会覆盖在它前面布局(JSX代码顺序)的组件的上方.

如果被遮盖住的组件需要处理触摸事件。比如我们在一个地图组件上覆盖了一个图像组件用来显示信息,又不想让这个图像组件影响用户手指拖动地图的操作,这时就需要使用图像组件从View组件继承得到的pointerEvents属性来解决这个问题.

**pointerEvents 是字符串类型的属性, 可以取值 none,box-none,box-only,auto.

  1. none 发生在本组件与本组件的子组件上的触摸事件都会交给本组件的父组件处理.
  2. box-none 发生在本组件显示范围内,但不是子组件显示范围内的事件交给本组件,在子组件显示范围内交给子组件处理
  3. box-only 发生在本组件显示范围内的触摸事件将全部由本组件处理,即使触摸事件发生在本组件的子组件显示范围内
  4. auto 视组件的不同而不同,并不是所有的子组件都支持box-none和box-only两个值,使用时最好测试下

下面是示例代码:

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View
} from 'react-native';

class AwesomeProject extends Component {
    constructor(props) {
        super(props); //必须有这句代码 父组件向子组件传递属性, 比如styles属性等
        this.state = {
            bigButtonPointerEvents: null //状态机变量控制大按钮是否工作
        };
        this.onBigButtonPressed = this.onBigButtonPressed.bind(this);
        this.onSmallButtonPressed = this.onSmallButtonPressed.bind(this);
    }

    onBigButtonPressed() {
        console.log('Big button pressed');
    }

    onSmallButtonPressed() {
        if (this.state.bigButtonPointerEvents === null) {
            console.log('big button will not responde');
            this.setState({bigButtonPointerEvents: 'none'});//改变状态机变量
            return;
        }
        console.log('big button will responde');
        this.setState({bigButtonPointerEvents: 'box-none'});//改变状态机变量
    }

    render() {
        return (
            //根View
            <View style={styles.container}
                  pointerEvents='box-none'>
                <Text style={styles.sButtonStyle}
                      onPress={this.onSmallButtonPressed}>
                    SmallButton
                </Text>
                <View style={styles.bButtonStyle}
                      pointerEvents={this.state.bigButtonPointerEvents}>
                    <Text style={{flex:1,fontSize: 20}}
                          onPress={this.onBigButtonPressed}
                          >
                        BigButton
                    </Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {   //根View样式
        flex: 1
    },
    sButtonStyle: {      // 小按钮的样式
        fontSize: 20,
        left: 130,
        top: 50,
        width: 150,
        height: 35,
        backgroundColor: 'green'
    },
    bButtonStyle: {     //大按钮的样式
        left: 130,
        top: 50,
        width: 150,
        height: 70,
        backgroundColor: 'grey',
        alignItems: 'center',
    }
});

AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

运行效果:


运行后,最开始时 Big Button可以正常工作, 因为Big Button父组件中pointerEvent为null, 然后当点击小按钮时,这时候pointerEvent值为none 大按钮就失效了。 当再按小按钮时,pointerEvent为 box-none, 大按钮就又可以处理事件了.

运行结果:


PS: 本来大按钮并没有单独用一个View组件嵌套, 直接把pointerEvent属性定义在大按钮的Text组件上, 在Android设备上发现没有效果, 有点不明觉厉了, 不知道是RN的Bug还是Android就是这种机制, 请大神解答了

更多精彩请关注微信公众账号likeDev,公众账号名称:爱上Android。


likeDev.jpg
React Native
Web note ad 1