Make your OverScrollLayout
2016-04-24 小文字
前言
手势处理在自定义控件中随处可见,诸如下拉,侧滑,加载更多等等,本文将利用手势相关的知识,来实现一个类似微信文章中过渡滑动交互。
下滑的处理在很早之前也写过几篇分别是简单的下拉,侧滑,原理基本类似,主要依赖的是offsetTopBotom,offsetLeftRight,Scroller;
在处理OverScroll的时候需要正确决定手势是否被拦截用于,滑动视图,或者分发至系统时间响应,根据内容区视图是否能滑动也有细节上的处理,这一块可以参照SwpieRefreshLayout的处理,即提供一个检测方法canChildScroolUp,针对内容view的类型单独处理;
下面是最终实现的效果:
控件定义
首先考虑一下,这个效果的UI组成,当滑动到顶部时可以继续滑动,展示底部的视图;因此滑动主要解决的是视图在Y轴上的偏移:
- 区分内容视图和背景视图
允许视图内包含一个背景View和一个内容View,为便于理解,参照FrameLayout,xml内第一个的view作为底视图,第二个作为内容视图
对子View的关系约定,可以放在合适的地方,比如inflate,或者第一次measure,layout时
- 视图排版
初始化视图,后需要根据规范对View的measure,layout响应处理
- 重载onInterceptTouchEvent
当手势在滑动且是上下滑动,超过touchslop时,开始拦截;
- 重载onTouch
这里可以开始根据move的具体值,调整view的offset
- 支持WebView
需要注意的是WebView在JellyBean之后内部实现有了很大变化,参考其源码实现可以证实,大量的具体逻辑都已经委托个了一个Provider实现类,这直接导致webview无法和其他view一样检测出其滑动位置;因此为了兼容WebView,需要在WebView内的OverScroll回调内手动再次处理offset,这一点实际上时参考了ChrisBean的Pull2Refresh的实现;
小结
在处理手势的时候进场会遇到效果不一致,这时候通过适量的log,可以更好地帮助开发者理解问题的出处;
完整的代码可以参考在github上的地址,欢迎各种star,for,issue:
https://github.com/avenwu/overscrolllayout
参考
- SwipeRefreshLayout
- Action-PullToRefresh