CoordinatorLayout 是Android design包提供的一個連動效果的容器。
背景
- 效果如下
頭部是一個容器,其實是和下面pager中的 Fragment
是復用的,也就說是這個界面上放了三個 Fragment
,Fragment
里面放的是 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
, 回來就嘗試重寫了 RecyclerView
的 onMeasure
方法:
@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,讓系統去支持他呢?