React Native通過修改ScrollableTabView和ViewPager來解決左右滑動(dòng)沖突的問題

1.背景

??在文章例子中的RN(以下用RN表示React Native)版本是0.43.3。RN官方和非官方提供了很多左右滑動(dòng)的控件和組件,作者使用的比較多的就是react-native-scrollable-tab-view和react-native-viewpager(之前作為一個(gè)Android開發(fā)者,對(duì)ViewPager情有獨(dú)鐘),它們?cè)趩为?dú)使用的時(shí)候并沒有什么問題,使用的方法也很簡(jiǎn)單。但是在實(shí)際的開發(fā)中,比如主頁面左右滑動(dòng)切換Tab,同時(shí)子頁面中又有左右切換輪播圖的組件,這個(gè)時(shí)候就會(huì)有左右滑動(dòng)沖突的問題,如果不加以處理的話,實(shí)際的效果體檢就會(huì)很差。俗話說站在巨人的肩膀上看得遠(yuǎn)(其實(shí)是作者比較菜,能力有限),本文就是在這兩個(gè)控件的基礎(chǔ)上進(jìn)行改進(jìn)來解決這個(gè)問題。

2.下載組件

??接下來要用到的兩個(gè)組件的Github地址分別為,
https://github.com/skv-headless/react-native-scrollable-tab-view
https://github.com/race604/react-native-viewpager
上面都有它們的介紹,相關(guān)Api以及如何使用的例子,在這里就不多加以介紹了,這里主要講如何修改去解決活動(dòng)沖突的問題

3.問題分析和解決思路

??那么問題來了,該怎么去解決這個(gè)滑動(dòng)沖突的問題呢?
??如果開發(fā)過Android項(xiàng)目可能知道,遇到這種問題的解決方式一般是使用ViewPager(父View),和ChildViewPager(子View),一般的做法就是在子View中接管Touch事件,當(dāng)子Viewr中可以進(jìn)行左滑和右滑操作時(shí),禁止父View的滑動(dòng),而當(dāng)子View滑動(dòng)到底的時(shí)候,把Touch事件交出來給父View,同時(shí)允許父View進(jìn)行滑動(dòng)?;镜慕鉀Q思路就是這樣的。首先在開始之前,對(duì)于RN下手勢(shì)事件不了解不熟悉的可以看下RN官方中文網(wǎng)站的介紹,地址如下:http://reactnative.cn/docs/0.43/gesture-responder-system.html

4.解決問題

??首先我們找到ViewPager中對(duì)于手勢(shì)控制的代碼,同時(shí)將我們的分析思路用代碼進(jìn)行實(shí)現(xiàn)

onMoveShouldSetPanResponder: (e, gestureState) => {
          let needMove=false;
          //手指從左往右滑動(dòng)
          if(gestureState.dx>0&&this.state.currentPage>0){
              needMove=true;
          }
          //手指從右往左滑動(dòng)
          if(gestureState.dx<0&&this.state.currentPage<this.props.dataSource.getPageCount()-1){
              needMove=true;
          }
        if (Math.abs(gestureState.dx) > Math.abs(gestureState.dy)&&needMove) {
          if (this.props.locked !== true && !this.fling) {
             this.props.hasTouch && this.props.hasTouch(true);
             return true;
          }
        }
      },

??判斷手指是從左往右滑動(dòng)的時(shí)候,并且當(dāng)處于非第0項(xiàng)的時(shí)候,或者手指是從右往左滑動(dòng)的時(shí)候,并且當(dāng)處于非最后一項(xiàng)時(shí)候,那么此時(shí)的手勢(shì)操作應(yīng)該交給子View,同時(shí)可以看到代碼
this.props.hasTouch && this.props.hasTouch(true); 意思就是告訴父View,此時(shí)我接管了手勢(shì)操作,并且本次滑動(dòng)操作成功。那么同理,當(dāng)不需要滑動(dòng)操作的時(shí)候應(yīng)該告訴父View,我不需要滑動(dòng)操作了。果然在ViewPager的release方法中找到了該方法的調(diào)用

var release = (e, gestureState) => {
      var relativeGestureDistance = gestureState.dx / deviceWidth,
          //lastPageIndex = this.props.children.length - 1,
          vx = gestureState.vx;

      var step = 0;
      if (relativeGestureDistance < -0.5 || (relativeGestureDistance < 0 && vx <= -1e-6)) {
        step = 1;
      } else if (relativeGestureDistance > 0.5 || (relativeGestureDistance > 0 && vx >= 1e-6)) {
        step = -1;
      }

      this.props.hasTouch && this.props.hasTouch(false);

      this.movePage(step, gestureState);
    }

??有了這些之后,我們就可以在父View之中根據(jù)這狀態(tài)來進(jìn)行相關(guān)的操作了

 <ScrollableTabView
                    locked={this.state.isLocked}
                      >
                    {this._getChildItem()}
 </ScrollableTabView>

 //true表示內(nèi)部需要滑動(dòng),此時(shí)外部需要lock住
    _hasTouch = (isTouch) => {
        this.setState({isLocked: isTouch})
  }

??通過對(duì)ScrollableTabView屬性的修改來進(jìn)行左右滑動(dòng)的控制。我們來看下分別在ios和android下的效果

ios上的效果
android上的效果

??從效果上來看偶爾會(huì)有誤觸的情況,但是總體上的效果還可以接受

5.最后

??作者接觸RN還不到一個(gè)月的時(shí)間,之前一直是Android開發(fā),能力有限,現(xiàn)在更多的是使用一些比較成熟的框架或者組件。當(dāng)然要根據(jù)一些業(yè)務(wù)的需求進(jìn)行修改。最后,奉上例子的Github地址:https://github.com/hzl123456/ChildViewPagerDemo
(記得修改ViewPager的代碼)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,983評(píng)論 25 709
  • React Native優(yōu)秀博客,以及優(yōu)秀的Github庫列表(很多英文資料源自于[awesome-react-n...
    董董董董董董董董董大笨蛋閱讀 11,010評(píng)論 4 162
  • 簡(jiǎn)短說明 收錄一些好用的RN第三方組件,以方便日常的使用,大家有什么推薦的也可以跟我說,我加進(jìn)去。如有冒犯,可以聯(lián)...
    以德扶人閱讀 43,904評(píng)論 44 214
  • 1 仲夏的家園 青山被挖去一半 透明的礦石出產(chǎn) 風(fēng)又改變了方向 黃土在風(fēng)中傾塌 沉入黃土 風(fēng)吹起頭發(fā) 玫紅色天空...
    雲(yún)歸閱讀 217評(píng)論 0 0
  • 法治與改革的關(guān)系 法治依據(jù):理性思維模式?習(xí)慣法理論模式? 古希臘法治原因: 人文精神,神人同形同性 城邦文化,自...
    cheeeeer閱讀 134評(píng)論 0 0

友情鏈接更多精彩內(nèi)容