CoordinatorLayout 22 到 23 一個大坑

CoordinatorLayout 是Android design包提供的一個連動效果的容器。

背景

  1. 效果如下

頭部是一個容器,其實是和下面pager中的 Fragment 是復用的,也就說是這個界面上放了三個 FragmentFragment里面放的是 RecyclerView 。 要求的效果是下面的 RecyclerView 滑動,頭部會跟著一起滑動, 中間的tab會懸停在頂部。

CoordinatorLayout design 22

很快想到了一個簡單的解決方案 CoordinatorLayout

run,跑起來效果一樣的,但發現一個無法接受的bug, 頭部view,無法像下面 viewpager 中的 RecyclerView 一樣拖拽上下滑動,想要界面滑動,只能拖拽下面的 RecyclerView ,可是頭部占屏幕那么大的空間卻不能滑動,很傷感。很快想到了一個簡單的修補方案,給頭部view追加一個 VelocityTracker , 然后傳遞給 AppBarLayout.Behavior,最終實現滑動:

但是總覺得太牽強,為什么不能正常的滾動呢?

CoordinatorLayout design 23

來到公司,同事說他之前做的一個界面,效果類似,但是可以滑動的,而且堅定頭部視圖是可以滑動的,我就奇怪了的,xml結構都一樣的,為什么我寫的demo就是不可以呢?可是我卻認為從設計層面上 AppBarLayout 這個容器本身應該不具備拖動效果,拖動是交給 另外一個 appbar_scrolling_view_behavior 是實現, 然后 AppBarLayout 通過觀察變化最終實現聯合滾動效果。

我就問了下,對方的design包的版本。

“23+”

無語,我是“22”。所以既然23可以滑動,那咱改下依賴版本到23。

run

坑。為什么頭部不見了的???

我只是改了個依賴版本,什么代碼都沒有改動啊。。。為什么東西不見了的???給了頭部一個高度才能顯示出來,哇,頭部確實可以滑動了的。

但是我頭部的數據都是后臺動態配置的,我怎么知道它的高度呢? 所以動態設置高度是不靠譜的。

于是大腦定型的就陷入了22和23 Google 改動了什么呢? 22不能滑動,但是顯示正常, 23非要給一個固定高度才可以顯示呢?

百思不得其解。

下午去廁所的路上,想起來,我的 Fragment 里面是 RecyclerView, 會不會是無法丈量高度導致的呢?想想以前 Listview 嵌套 GridView 或者 scrollview 之類的 都要自己重寫一下 onMeasure, 回來就嘗試重寫了 RecyclerViewonMeasure 方法:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>> 2,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightSpec);
    }

run。

success。

不僅可以滑動,而且支持 wrap_content.

完美!

寫在最后

至于 com.android.support:design 從 22 到 23 改動了什么,導致不支持子view 中的 RecyclerView 設置高度為 wrap_content。后面有空的話在深入研究一下。

雖然是一個很小的問題,但要給自己一個教訓,陷入定型思維,一直盯著xml看,卻忘記了內在的實現。

雖然有條條大路通羅馬,但盡量遵循用官方的做法。比如這個其實我做之前,想的是很簡單的自己去監聽 RecyclerView 的位移變化,動態改變頭部view,從而實現聯動效果,但同事說之前搞過類似的,可以用官方的,我也覺得這樣不錯,因為后期維護成本相對而言會很低。再比如頭部不能滾動,我就自己手巧的實現了拖動效果,但官方 23 就修復了這個問題實現了拖動,那為什么不升級到23,讓系統去支持他呢?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容