这一次拆解的是今日头条的关注页面:点击关注的头像会弹出一个文章列表。在边界拖拽会出现关闭提示。这次同时实现了Android端和IOS端的效果。
先讲解Android端的实现吧,毕竟我是个Android开发仔呀
效果如下图:
Android端
弹出来的页面可以左右切换,每个页面是单独的列表,能上下滑动,所以这里直接用viewPager+recycelrView实现。
当viewPager不能左右滑动的时候,移动整个viewPager,出现文字提示,当滑动距离超过阈值时,文字改变。
当手指松开时,若滑动距离未到达阈值,回弹;否则结束页面。
同样,当recyclerView在顶部不能滑动时,移动recyclerView,出现提示,后续跟viewPager一致故不再赘述。
ReBoundLayout
这里的回弹我自定义了一个回弹布局,下面介绍一下回弹布局的几个重要方法:
onInterceptTouchEvent()
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//记录坐标
break;
case MotionEvent.ACTION_MOVE:
int difX = (int) (ev.getX() - mDownX);
int difY = (int) (ev.getY() - mDownY);
if (orientation == LinearLayout.HORIZONTAL) {
.....
if (水平滑动) {
if (!innerView.canScrollHorizontally(-1) && difX > 0) {
//右拉到边界
return true;
}
if (!innerView.canScrollHorizontally(1) && difX < 0) {
//左拉到边界
return true;
}
}
} else {
......
if (竖直滑动) {
if (!innerView.canScrollVertically(-1) && difY > 0) {
//下拉到边界
return true;
}
if (!innerView.canScrollVertically(1) && difY < 0) {
//上拉到边界
return true;
}
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
......重置变量
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
当控件方向为横向且滑动为水平滑动时,检测innerView能否在该方向上滑动;若不能,则拦截事件,交给自身处理(纵向同理)。
拦截事件后,在onTouchEvent()进行处理,实现移动和回弹。
@Override
public boolean onTouchEvent(MotionEvent eve