ViewPagerHeader滚动

【Update 2015.09.06】使用新的Android Design Support Library中的 CoordinatorLayout可以完美实现这个功能。


这不太会起标题的名字了。简单来说想在 ViewPager 上方加一个 Header,当 ViewPager 内部滚动时,同时或者优先滚动顶部的 Header。

总结一下,大概有3种方案。

  1. Android 5.0 电话里联系人。
    当 ViewPager 内部列表向上滚动时,Actionbar 滚动隐藏,向下滚动时跟着出现。

    不过这是 API 21 的新特性(setHideOnContentScrollEnabled(boolean hideOnContentScroll)setNestedScrollingEnabled (boolean enabled)),不能广泛使用。

  2. Google Play 应用列表。
    首先需要给 ViewPager 内部的 ListView 加入和外部同样高度的透明Header,使用 onScrollListener 监听滚动,传递到外部来同时移动 ViewPager 的 Header。

    相比第一种,当滚动到中间然后稍微下拉出 Header 时,Header 自动展开会遮挡列表顶部数据。而且当列表没有数据或者数据不足一屏就不能触发 onScrollListener ,没法滚动了…… 另外,因为 ListView 顶部填充了一个透明的 Header 占位,会导致滚动条被遮挡,列表顶部反馈效果也被遮挡了。

  3. 豌豆荚 “手机内容管理” 界面。
    优先吸顶 Viewpager 的 Header。然后再滑动 Viewpager 内部列表。这样在上下滑动列表时,Header 不会动来动去干扰视线。

    在Viewpager 外层处理 onInterceptTouchEvent(MotionEvent ev)onTouchEvent(MotionEvent ev) ,拦截滚动等事件,优先处理 Header 滚动。但由于处理触控的事件分发限制,当 Header 收缩后,需要再次抬手才能触发列表滑动,造成不连贯。

对比一下这3种方案,感觉还是第三个相对好一些。

Demo 地址,具体见代码。因为主要的动画移动,需要根据实际情况在Activity来做处理,所以没有做成自定义控件。顺便提供了Fling速率等。

ViewPagerHeaderScrollDemo

另外,如果对事件分发不太清楚,推荐阅读 Android 编程下 Touch 事件的分发和消费机制

Author

Relex

Android Developer