協(xié)調(diào)者布局頭部無法上滑解析

場景

某個(gè)界面的頭部HeaderBehavior是動態(tài)生成的,高度不定迈窟,某次在頭部超過整屏的時(shí)候缝其,上滑顯示列表挎塌,再下拉,當(dāng)我再次想要上滑的時(shí)候内边,發(fā)現(xiàn)無法滑動了

原因

  • 協(xié)調(diào)者布局會根據(jù)手指觸摸的落點(diǎn)是否在頭部布局的范圍內(nèi)來判斷由HeaderBehavior來處理滑動還是RecycleView或者NestedScrollerView來處理滑動
 case MotionEvent.ACTION_DOWN: {
                mIsBeingDragged = false;
                final int x = (int) ev.getX();
                final int y = (int) ev.getY();
                if (canDragView(child) && parent.isPointInChildBounds(child, x, y)) {
                    mLastMotionY = y;
                    mActivePointerId = ev.getPointerId(0);
                    ensureVelocityTracker();
                }
                break;
            }
  public boolean isPointInChildBounds(View child, int x, int y) {
        final Rect r = acquireTempRect();
        getDescendantRect(child, r);
        try {
            return r.contains(x, y);
        } finally {
            releaseTempRect(r);
        }
    }
  • AppBarLayout對滑動的子View有弱引用(也就是RecycleView或者NestedScrollerView)
  • 當(dāng)這個(gè)弱引用存在的時(shí)候判斷子View是否能繼續(xù)滑動榴都,如果能繼續(xù)滑動,則交由子View處理(也就是這里的問題導(dǎo)致我Head過大時(shí)漠其,落點(diǎn)在Head缭贡,導(dǎo)致無法滑動),如果子View不能滑動辉懒,在onTouchEvent事件中把MotionEvent.ACTION_DOWN交給HeaderBehavior自己來處理
   @Override
        boolean canDragView(AppBarLayout view) {
            if (mOnDragCallback != null) {
                // If there is a drag callback set, it's in control
                return mOnDragCallback.canDrag(view);
            }

            // Else we'll use the default behaviour of seeing if it can scroll down
            if (mLastNestedScrollingChildRef != null) {
                // If we have a reference to a scrolling view, check it
                final View scrollingView = mLastNestedScrollingChildRef.get();
                return scrollingView != null && scrollingView.isShown()
                        && !ViewCompat.canScrollVertically(scrollingView, -1);
            } else {
                // Otherwise we assume that the scrolling view hasn't been scrolled and can drag.
                return true;
            }
        }

解決方案

那么從上述分析中我們可以得出兩點(diǎn)阳惹,如果要滑動,以我鄙見眶俩,有兩個(gè)方案莹汤,想辦法讓Header來處理,或者同時(shí)讓RecycleView來接管不屬于他的事件

  • 先看怎么讓Header來處理

從上述部分代碼我們可以看到canDragView在有弱引用的時(shí)候返回為true的條件有scrollingView(此時(shí)為recycleview)不為空颠印,且是顯示狀態(tài)纲岭,且canScrollVertically返回為false

  • 那么問題來了,recycleview的canScrollVertically這個(gè)方法什么時(shí)候返回為false
      /**
        * Query if vertical scrolling is currently supported. The default implementation
        * returns false.
        *
        * @return True if this LayoutManager can scroll the current contents vertically
        */
       public boolean canScrollVertically() {
           return false;
       }
  • 默認(rèn)返回false线罕,但是當(dāng)有LayoutManager為豎直方向是返回為true止潮。OK,那么我們只要在自己的recycleview中重新canScrollVertically方法就好了(經(jīng)我測試钞楼,默認(rèn)返回為false可以解決無法滑動的問題喇闸,但是為了更嚴(yán)謹(jǐn)一點(diǎn),盡量還是做一層判斷询件,某些第三方可能將下拉刷新的邏輯引入了canScrollVertically的判斷燃乍,默認(rèn)返回為false可能導(dǎo)致無法下拉刷新)
  • 再看看怎么讓RecycleView來處理
  • 簡單,在 AppBarLayout的touch監(jiān)聽中直接把事件交給recycleview
 appbarlayout.setOnTouchListener(new View.OnTouchListener() {
          @Override
          public boolean onTouch(View v, MotionEvent event) {
              recycleview.dispatchTouchEvent(event);
              return false;
          }
      });
  • 經(jīng)我測試宛琅,有效刻蟹,并且不會對header中本身的控件點(diǎn)擊事件行為產(chǎn)生影響

結(jié)語

雖然解決了問題,也提供了兩個(gè)方案嘿辟,但是從代碼來看舆瘪,我的解決方案都是很粗暴的片效,短時(shí)間來看沒有什么毛病,但是真的沒有毛病嗎英古?這是要打一個(gè)問號的

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末淀衣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哺呜,更是在濱河造成了極大的恐慌,老刑警劉巖箕戳,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件某残,死亡現(xiàn)場離奇詭異,居然都是意外死亡陵吸,警方通過查閱死者的電腦和手機(jī)玻墅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來壮虫,“玉大人澳厢,你說我怎么就攤上這事∏羲疲” “怎么了剩拢?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饶唤。 經(jīng)常有香客問我徐伐,道長,這世上最難降的妖魔是什么募狂? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任办素,我火速辦了婚禮,結(jié)果婚禮上祸穷,老公的妹妹穿的比我還像新娘性穿。我一直安慰自己,他們只是感情好雷滚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布需曾。 她就那樣靜靜地躺著,像睡著了一般祈远。 火紅的嫁衣襯著肌膚如雪胯舷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天绊含,我揣著相機(jī)與錄音桑嘶,去河邊找鬼。 笑死躬充,一個(gè)胖子當(dāng)著我的面吹牛逃顶,可吹牛的內(nèi)容都是我干的讨便。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼以政,長吁一口氣:“原來是場噩夢啊……” “哼霸褒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起盈蛮,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤废菱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后抖誉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殊轴,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年袒炉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旁理。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡我磁,死狀恐怖孽文,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夺艰,我是刑警寧澤芋哭,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站郁副,受9級特大地震影響楷掉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜霞势,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一烹植、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愕贡,春花似錦草雕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至憨琳,卻和暖如春诫钓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背篙螟。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工菌湃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遍略。 一個(gè)月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓惧所,卻偏偏與公主長得像骤坐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子下愈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容