安卓控件日常开发Bug小记

CoordinatorLayout 22 到 23 一个大坑

2017-09-22  本文已影响98人  IMSk

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,让系统去支持他呢?

上一篇下一篇

猜你喜欢

热点阅读