在React Native界面開發中, 如果使用絕對定位布局,在代碼運行時的某個時刻有可能會遮蓋住它的下方的某個組件。這是因為絕對定位只是說這個組件的位置由它父組件的邊框決定。 絕對定位的組件可以被認為會覆蓋在它前面布局(JSX代碼順序)的組件的上方.
如果被遮蓋住的組件需要處理觸摸事件。比如我們在一個地圖組件上覆蓋了一個圖像組件用來顯示信息,又不想讓這個圖像組件影響用戶手指拖動地圖的操作,這時就需要使用圖像組件從View組件繼承得到的pointerEvents屬性來解決這個問題.
**pointerEvents 是字符串類型的屬性, 可以取值 none,box-none,box-only,auto.
- none 發生在本組件與本組件的子組件上的觸摸事件都會交給本組件的父組件處理.
- box-none 發生在本組件顯示范圍內,但不是子組件顯示范圍內的事件交給本組件,在子組件顯示范圍內交給子組件處理
- box-only 發生在本組件顯示范圍內的觸摸事件將全部由本組件處理,即使觸摸事件發生在本組件的子組件顯示范圍內
- 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。