Android UI的收集android技术专栏Android知识

高仿京东下拉刷新,轻松上手!

2016-11-03  本文已影响1039人  ringtone
直接进入主题,先来看一下京东的实现效果:
jd.gif
以及我自己的实现效果:
myjd.gif

实现过程

1.下拉原理
layout.png

整个布局为继承自LinearLayout的Viewgroup,分为头部及下面的列表部分,通过设置HeaderView的topMargin属性为负使HeaderView向屏幕上方偏移。
初始化时设置HeaderView的topMargin为负的HeaderView的高度可以将HeaderView完全隐藏,从而屏幕中只看得到列表部分。下拉过程中根据手指划过的距离不断更新HeaderView的topMargin值来改变HeaderView的可视范围从而达到下拉的效果。

2.效果实现

观察京东客户端的下拉过程,可以看出下拉过程中快递员和包裹是不断放大的并且透明度在增加,当HeaderView完全可见时达到最大值并且快递员“取到”包裹,松开手后快递员开始“拼命送货”。

其中放大效果我是用ScaleDrawable实现,通过手指划过的位移改变Drawable的level从而改变图片的大小,不熟悉ScaleDrawable的可以参考Android Drawable之ScaleDrawable。松开手后快递员奔跑是由帧动画实现。

3.关键代码

拦截部分:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {    
    switch (event.getAction()) {        
        case MotionEvent.ACTION_DOWN:           
             mTouchY = event.getY();
             break; 
        case MotionEvent.ACTION_MOVE:
             float dy = event.getY() - mTouchY; 
            //当RecyclerView移到顶部并且手指向下滑动时,拦截事件,由自己处理Touch事件           
             if (dy > 0 && canPull)              
                  return true;       
        case MotionEvent.ACTION_UP:  
        default:            
             break;    
    }    
    return false;
}

滑动部分:

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            float dy = event.getY() - mTouchY;
            mTouchY = event.getY();
            if (Math.abs(mTouchY)<touchSlop)
                break;
            if (mCurrentStatus != STATUS_REFRESHING) {
                //除以2是增加下拉的阻力感
                headerLayoutParams.topMargin += dy / 2;
                //此时为向上滑动到头部完全隐藏的情况,继续滑动的话应该交由RecyclerView处理了,故返回false自己不消耗事件。
                if (headerLayoutParams.topMargin<=hideHeaderHeight){
                    headerLayoutParams.topMargin=hideHeaderHeight;
                    mHeaderView.requestLayout();
                    return false;
                }
                //此时为头部完全显示的情况
                if (headerLayoutParams.topMargin>=0){
                    mCurrentStatus = STATUS_RELEASE_TO_REFRESH;
                }else {
                    mCurrentStatus = STATUS_PULL_TO_REFRESH;
                    //改变图片的大小及透明度
                    onLevelChanged((hideHeaderHeight-headerLayoutParams.topMargin)*100/hideHeaderHeight);
                }
                mHeaderView.requestLayout();
            }
            break;
        case MotionEvent.ACTION_UP:
        if (mCurrentStatus == STATUS_PULL_TO_REFRESH){
            //属性动画实现平滑滚动
           headerAnimation(headerLayoutParams.topMargin,hideHeaderHeight,350,null);
        }else if (mCurrentStatus == STATUS_RELEASE_TO_REFRESH){
            mCurrentStatus = STATUS_REFRESHING;
            headerAnimation(headerLayoutParams.topMargin,0,250,null);
            if (listener!=null)
                listener.onRefresh();
        }
        break;
    }
    updateHeaderView();
    lastStatus = mCurrentStatus;
    return super.onTouchEvent(event);
}

<br />

具体代码可以参考https://github.com/tangr2015/JDPullToRefresh

<br />
<br />

参考Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

上一篇 下一篇

猜你喜欢

热点阅读