this.panResponder = PanResponder.create({
/***************** 要求成為響應(yīng)者 *****************/
// 單機手勢是否可以成為響應(yīng)者
onStartShouldSetPanResponder: (evt, gestureState) => true,
// 移動手勢是否可以成為響應(yīng)者
onMoveShouldSetPanResponder: (evt, gestureState) => true,
// 攔截子組件的單擊手勢傳遞,是否攔截
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
// 攔截子組件的移動手勢傳遞,是否攔截
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
/***************** 響應(yīng)者事件回調(diào)處理 *****************/
// 單擊手勢監(jiān)聽回調(diào)
onPanResponderGrant: (e, gestureState) => {
console.log('onPanResponderGrant==>' + '單擊手勢申請成功,開始處理手勢');
this._onPanResponderGrant(e);
},
// 移動手勢監(jiān)聽回調(diào)
onPanResponderMove: throttle((e, gestureState) => {
console.log('onPanResponderMove==>' + '移動手勢申請成功,開始處理手勢' + `${gestureState}`);
this._onPanResponderMove(e, gestureState);
}, 200),
// 手勢動作結(jié)束回調(diào)
onPanResponderEnd: (evt, gestureState) => {
console.log('onPanResponderEnd==>' + '手勢操作完成了,用戶離開');
this._onPanResponderEnd(evt);
},
// 手勢釋放, 響應(yīng)者釋放回調(diào)
onPanResponderRelease: (e, gestureState) => {
// 用戶放開了所有的觸摸點,且此時視圖已經(jīng)成為了響應(yīng)者嫉到。
// 一般來說這意味著一個手勢操作已經(jīng)成功完成。
this._onPanResponderRelease(e, gestureState);
console.log('onPanResponderRelease==>' + '放開了觸摸,手勢結(jié)束');
},
// 手勢申請失敗,未成為響應(yīng)者的回調(diào)
onResponderReject: (e, gestureState) => {
// 申請失敗,其他組件未釋放響應(yīng)者
console.log('onResponderReject==>' + '響應(yīng)者申請失敗');
this._onPanResponderRelease(e, gestureState);
},
// 當(dāng)前手勢被強制取消的回調(diào)
onPanResponderTerminate: e => {
// 另一個組件已經(jīng)成為了新的響應(yīng)者局装,所以當(dāng)前手勢將被取消
console.log('onPanResponderTerminate==>' + '由于某些原因(系統(tǒng)等),所以當(dāng)前手勢將被取消');
return true;
},
onShouldBlockNativeResponder: (evt, gestureState) => {
return true;
}
});
需求是多個可以拖拽的對象所以需要知道每次是拖拽哪個,而調(diào)用方法需要用 {...this.panResponder.panHandlers}
解構(gòu)之后得到的json通過props傳遞給組件座泳,使得組件變成響應(yīng)者呀邢,打印{...this.panResponder.panHandlers}
[圖片上傳失敗...(image-3e7074-1580929245556)]
多個拖拽就不能知道是哪個變成了響應(yīng)者
- 不用解構(gòu),給View綁定事件洒沦,傳遞index
Animated.View
綁定事件,如
<Animated.View
onResponderMove={(nativeEvent, gestureState) => this.onResponderMove(index, nativeEvent, gestureState}
>
將index作為參數(shù)傳遞過去就知道是哪項作為了響應(yīng)者价淌,但是申眼,參數(shù)中g(shù)estureState是undefined
[圖片上傳失敗...(image-5cb757-1580929245556)]
官網(wǎng)中說:它提供了一個對觸摸響應(yīng)系統(tǒng)響應(yīng)器的可預(yù)測的包裝瞒津。對于每一個處理函數(shù),它在原生事件之外提供了一個新的gestureState對象括尸。
所以不用PanResponder.create
得不到gestureState對象
2.通過重寫解構(gòu)出來的{...this.panResponder}
后的onResponderGrant
將index放到state中
List.map(li => (
<Animated.View
style={styles.scheduleMoveImgView}
{...this.panResponder.panHandlers}
onResponderGrant={e => {
this.touchY = e.nativeEvent.locationY - 12;
this.initHeight = ((li.end - li.start) / 1800) * initOneHeight;
this.dragItem = li;
this.setState({
isMove: true,
movingHeight: this.initHeight,
dragIndex: index
});
}}
>
</Animated.View>
))
項目中使用了第二種方法巷蚪,因為拖拽時需要得到gestureState對象
[站外圖片上傳中...(image-ff863f-1580929245556)]
<ScrollView
style={{ flex: 1 }}
scrollEnabled={!isMove}
ref={view => {
this.areaScrollView = view;
}}
>
<View style={styles.scheduleList}>
{
scheduleList.map((li, index) => ())
}
</View>
<View style={styles.lineWrap}>
{
scheduleList.map((li, index) => ())
}
</View>
<View style={styles.scheduleSelectList}>
{
scheduleSelectList.map((li, index) => ())
}
</View>
</ScrollView>
ScrollView的children有3個View,scheduleList
是0-24小時的間距濒翻,lineWrap
是今天線屁柏,絕對定位,scheduleSelectList
是選中的時間段肴焊,絕對定位前联。
android中的坑
[圖片上傳失敗...(image-8bd84e-1580929245556)]
[圖片上傳失敗...(image-d90c41-1580929245556)]
在android里面只有1/4的區(qū)域能夠點擊,ios沒事娶眷,截圖中綠色和黃色的交界處才能點擊似嗤。原來只有圖標(biāo)能點擊(圓圈灰色X,2424)届宠,在手機中點擊體驗不好烁落,改成黃色區(qū)域能夠點擊(5050),因為黃色刪除按鈕和拖動按鈕都是絕對定位,通過拖動豌注,動態(tài)設(shè)置box(藍色區(qū)域)的height伤塌。
box{
position: 'absolute',
top,
height
}
藍色區(qū)域外的區(qū)域點擊在android中無效
解決方案
<View> // 青色區(qū)域,top - 25, 高度 + 50
<View></View> // 內(nèi)部邊框區(qū)域 margin 25
</View>
[圖片上傳失敗...(image-6670c6-1580929245556)]
這個時候轧铁,按鈕就在區(qū)域內(nèi)了每聪,可以點擊按鈕全部位置了
接下來就遇到第二個問題
2個box之間間隔一個區(qū)域,這個時候就不能選擇這個區(qū)域了齿风,2個box區(qū)域重疊药薯,上面一個box的高度向下25,下面一個box的top向上25救斑,中間的一個區(qū)域不能點擊
設(shè)置區(qū)域position: 'absolute', zIndex: 100
會導(dǎo)致按鈕的3/4
能點擊童本,左下角1/4
不能點擊問題
[圖片上傳失敗...(image-11774f-1580929245556)]
解決方案
<View> // 一塊區(qū)域
<View></View> // 不定位
<View></View> // 定位(寬度80%)
</View>
解決之后
[圖片上傳失敗...(image-7bd580-1580929245556)]
紅色區(qū)域在andriod能點擊選中
但是在ios中紅色區(qū)域是在青色的內(nèi)部(心中感到ios和anroid都有不同的渲染機制,都有坑)脸候,只有設(shè)置外層的View的zIndex: 100大于青色區(qū)域才行穷娱,ios中內(nèi)部View的zIndex是在外層zIndex 的基礎(chǔ)上的。所以方案失敗运沦。(如果設(shè)置外面的View的zIndex: 100,就不能設(shè)置width: 80%泵额, 因為每個區(qū)域都有一個下邊框,80%的話下邊框的長度也變成了80%了携添,可以通過設(shè)置內(nèi)部的View的width為Dimensions.get('window').width*0.8 這時候的下邊框就是一樣了梯刚,最終沒采用這種方案)
最終方案
通過設(shè)置 scheduleList.map((li, index) => ()) 生成不同時間段的高為0.5的下邊框(絕對定位), 內(nèi)部View展示為80%薪寓,效果就是上圖一樣了
rn的體驗等級亡资,能用,湊合向叉,流暢锥腻,絲滑