神之bug 嵌套R(shí)ecyclerView謎之滾動(dòng)

序言

有些bug,來(lái)無(wú)影,去無(wú)蹤。你不知道它怎么產(chǎn)生的。比如下面這個(gè),描述一下癥狀,每次Fragment切換的時(shí)候,頁(yè)面都會(huì)自己滾動(dòng)一點(diǎn)好像要把自己對(duì)齊。

這里寫圖片描述

布局如下


這里寫圖片描述

XML實(shí)現(xiàn)如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:id="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/TopBarHeight"
        android:background="@color/colorPrimary">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:src="@drawable/ic_logo" />
    </RelativeLayout>

    <com.trs.library.widget.statusviewlayout.StatusViewLayout
        android:id="@+id/status_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.scwang.smartrefresh.layout.SmartRefreshLayout
            android:id="@+id/ptr"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:srlEnableHeaderTranslationContent="true"
            app:srlEnableLoadmore="true">

            <com.scwang.smartrefresh.layout.header.ClassicsHeader
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:srlClassicsSpinnerStyle="FixedBehind" />

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white" />

            <com.scwang.smartrefresh.layout.footer.ClassicsFooter
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </com.scwang.smartrefresh.layout.SmartRefreshLayout>

    </com.trs.library.widget.statusviewlayout.StatusViewLayout>
</LinearLayout>

用的是最近比較火的SmartRefreshLayout。

分析

一開始我看到的是這樣的

這里寫圖片描述

1.自定義Layout出問(wèn)題

每一次切換回來(lái)最頂部的自定義Layout都顯示不全,也就是下面這個(gè),實(shí)現(xiàn)可以看我的上一篇博客三角形兼梯形布局

這里寫圖片描述

于是把這個(gè)控件替換成RelativeLayout高度固定,但是bug依然存在。因此排除此項(xiàng)。

2.SmartRefreshLayout的問(wèn)題

這個(gè)頁(yè)面使用的了SmartRefreshLayout,詳情見這里Android智能下拉刷新框架-SmartRefreshLayout
雖然是比較有名的第三方庫(kù),但是bug也是可能有的。所以開始閱讀他的源碼,但是在閱讀了他的源碼以后,發(fā)現(xiàn)沒(méi)什么問(wèn)題。通過(guò)打斷點(diǎn)發(fā)現(xiàn),在頁(yè)面發(fā)生滾動(dòng)的時(shí)候它的方法根本就沒(méi)有調(diào)用。

3.手機(jī)的bug

我懷疑是不是開啟了類屬于三星的眼動(dòng)功能,于是用了同事的小米進(jìn)行測(cè)試,排除。

4.RecyclerView的問(wèn)題

既然排除了所以可能性,那么最不可能的答案也是答案了。在RecyclerView中負(fù)責(zé)滾動(dòng)的是LayoutManger,于是我自定義了LayoutManger,發(fā)現(xiàn)確實(shí)有Log輸出
測(cè)試代碼如下:

 @Override
    protected RecyclerView.LayoutManager getLayoutManager() {
        return new MyLayoutManger(getActivity());
    }

    private class MyLayoutManger extends LinearLayoutManager {

        public MyLayoutManger(Context context) {
            super(context);
        }

        @Override
        public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
            Log.i("zzz", "MyLayoutManger scrollHorizontallyBy dy=" + dy);
            return super.scrollVerticallyBy(dy, recycler, state);
        }

    }

每一次切換回來(lái)的Log輸出

10-13 16:29:53.968 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=53
10-13 16:29:53.988 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=63
10-13 16:29:53.998 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=53
10-13 16:29:54.018 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=39
10-13 16:29:54.038 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=36
10-13 16:29:54.048 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=26
10-13 16:29:54.068 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=21
10-13 16:29:54.088 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=16
10-13 16:29:54.108 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=12
10-13 16:29:54.118 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=8
10-13 16:29:54.138 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=7
10-13 16:29:54.158 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=5
10-13 16:29:54.168 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=3
10-13 16:29:54.188 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=1
10-13 16:29:54.208 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=2
10-13 16:29:54.238 6990-6990/com.trs.cqjb.gov I/zzz: MyLayoutManger scrollHorizontallyBy dy=1

調(diào)用鏈如下


這里寫圖片描述

可以看出來(lái)都是Framework層的調(diào)用,沒(méi)有我們自己的代碼。也沒(méi)有SmartRefreshLayout的代碼。既然找到問(wèn)題了,就去Google。果然這是RecyclerView嵌套的bug。


這里寫圖片描述

總結(jié)

在遇到bug的時(shí)候,一定要耐心仔細(xì),從最容易出錯(cuò)的地方找起,可以先從自己找齊,但是如果自身沒(méi)有問(wèn)題,也不能放過(guò)第三方庫(kù),認(rèn)為第三方庫(kù)就完美無(wú)缺。當(dāng)遇到第三方庫(kù)有問(wèn)題的時(shí)候首先可以去翻閱Github中的issues這樣會(huì)更快捷,但是如果還沒(méi)有人閱讀這類問(wèn)題,那么我還得去read the funk source code (我曾經(jīng)就通過(guò)跟蹤斷點(diǎn),找出張鴻洋一個(gè)庫(kù)里面代碼的邏輯問(wèn)題,然后去提了issues。)因此當(dāng)我們遇到bug時(shí)不要怕,要平心靜氣,理性分析,合理假設(shè),逐一排除。

最后編輯于
?著作權(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閱讀 179,039評(píng)論 25 709
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議。它實(shí)...
    香橙柚子閱讀 24,755評(píng)論 8 183
  • S君,是我高中時(shí)的學(xué)長(zhǎng),俊朗的側(cè)顏,總是一臉明媚的笑,那也是我見過(guò)最好看的笑容,頎長(zhǎng)的身姿,加上動(dòng)聽的聲線,這絕對(duì)...
    云蒹閱讀 381評(píng)論 0 0
  • 萬(wàn)歷四十四年,努爾哈赤建國(guó)。 四十六年正月,對(duì)明宣戰(zhàn)。 四月,攻撫順。 萬(wàn)歷四十八年,萬(wàn)歷皇上駕崩。 萬(wàn)歷四十八年...
    一米颺光v閱讀 382評(píng)論 0 0
  • 2017.11.5 星期日 晴 農(nóng)歷九月十七 今天早上睡的正酣,被老公推醒了,說(shuō)女兒喊我。原來(lái)已經(jīng)到點(diǎn)女兒要起床了...
    小幸福vs茹萍閱讀 256評(píng)論 0 0

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