zoukankan      html  css  js  c++  java
  • 万能下拉刷新效果实现

    继上次学习了如何实现QQ汽泡效果之后,这次来实现一个新的效果,几乎是每个项目不可获缺的效果,那就是下拉刷新,由于非常之熟悉了,就不过多说明了,另外这里依然也涉及到对事件的处理,应该说是基于这个效果的实现进一步来巩固对android的事件分发理解,说不多说进入正题。

    效果演示:

    先来看一下最终要实现的效果:

    当然市面上下拉刷新的效果千奇百怪,对于前阵子又融资了的美团在他们的美团app中就有一个下拉刷新效果,而下拉下来会有个绿色的小人蹦出来,我想用过美团的应该印象也非常深刻,那如果学会了这次的这种比较传统的效果,其美团的这种下拉效果实现起来也就不难了,而且这次要实现的是一个通用的下拉刷新,也就是应用到任何内容上都能实现下拉的效果,当然如今在github上也已经有非常成熟的三方开源方案了,但是要能自己从无到有的实现出来那也是挺美的一件事,所以下面一步步来剖析它。

    划分区域:

    在正式实现之前先来对效果进行一下分析:

    所以第一步则需要划分出这些区域,最后落实到代码上来,首先新建一个类用来表示咱们的下拉刷新控件,由于这里明显是一个垂直结构的布局,所以可以基于LinearLayout进行扩展,而不用继续最原生的View去写了,这样就不用来做测绘工作了,如下:

    /**
     * 下拉刷新控件
     * 初步划分区域
     */
    public class RefreshLayout extends LinearLayout {
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            //TODO
        }
    }

    然后将其声明在XML布局中:

    然后初始化一个头部视图,这里先直接上代码,呆会再解释:

    /**
     * 下拉刷新控件
     * 初步划分区域
     */
    public class RefreshLayout extends LinearLayout {
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            LinearLayout wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    }

    为啥不添加一个实际的头部,而是添加了一个空的视图,这是因为为了将来的扩展,因为这时一个通用的下拉刷新,未来的头部的形式可能千变万化,比如未来的美团小人蹦出来的效果,其整体的下拉形式差不多,只是头部的动画会有变化,所以不同形式的头部需要作为上面整个头部视图的子视图,这样未来想要更换效果只要替换掉里面的子视图既可,所以这里需要理解理解。好了,这时运行看下效果:

    呃,啥效果都木有了,原本不是有个TextView的文本内容么?这是由于咱们木有对LinearLayout设置方向,于是乎加上它:

    嗯,内容区域看到了,但头部视图还木有出来呀,这是由于头部视图是wrap_content,而它并未添加任何子视图,所以当然看不到了,这时为了看效果先将头部的高度写死一个值:

    再来运行:

    好了,区域目前已经划分好了,记得将这个写死的代码还原,接着下一步。

    添加自定义头部视图并隐藏:

    在第一步划分区域对于头部区域提到了子头部视图的概念,所以接下来在头部区域中添加子视图,而子视图的效果就是带箭头和文字的,所以先准备具体头部视图的布局文件:

    view_refresh_header_normal.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">
    
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="15dp"
            android:layout_marginRight="10dip"
            android:layout_marginTop="15dp">
    
            <ImageView
                android:id="@+id/iv_normal_refresh_header_arrow"
                android:layout_width="28dp"
                android:layout_height="28dp"
                android:layout_gravity="center"
                android:src="@mipmap/refresh_head_arrow" />
    
            <ImageView
                android:id="@+id/iv_normal_refresh_header_loading"
                android:layout_width="34dp"
                android:layout_height="34dp"
                android:src="@drawable/refresh_loding"
                android:visibility="invisible" />
        </FrameLayout>
    
        <TextView
            android:id="@+id/tv_normal_refresh_header_status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="15dp"
            android:layout_marginTop="15dp"
            android:text="下拉刷新"
            android:textColor="@android:color/white"
            android:textSize="14sp" />
    </LinearLayout>

    其中用到两个资源图:

    ①、箭头:

    ②、Loading,这个Loading是由一个针动画实现的,每帧图片如下:

    而动画文件为:

    <?xml version="1.0" encoding="utf-8"?>
    <!--animation-list:帧动画
     每一个item都是一帧
     android:oneshot="false" 表示动画一直执行-->
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false" >
    
        <item
            android:drawable="@mipmap/refresh_loading01"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading02"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading03"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading04"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading05"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading06"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading07"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading08"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading09"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading10"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading11"
            android:duration="100"/>
        <item
            android:drawable="@mipmap/refresh_loading12"
            android:duration="100"/>
    
    </animation-list>

    这时将这个具体的头部布局添加到头部视图中:

    /**
     * 下拉刷新控件
     * 添加自定义头部视图并隐藏
     */
    public class RefreshLayout extends LinearLayout {
    
        /* 头部根布局 */
        private LinearLayout wholeHeaderView;
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.setOrientation(LinearLayout.VERTICAL);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
            initSelfHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    
        //初始化具体的头部内容
        private void initSelfHeaderView() {
            View selfHeaderView = View.inflate(getContext(), R.layout.view_refresh_header_normal, null);
            selfHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.addView(selfHeaderView);
        }
    }

    这时编译运行:

    嗯,完美,但接下来需要做一下头部隐藏的效果,而这个隐藏并非指直接将这个头部视图给设置成GONE,而是应该适应未来随着手指的滑动而一点点改变头部的高度,那采用什么办法可以让头部隐藏掉呢? 这里其实给具体的头部View设置padding就能达到,下面来实验下:

    首先给paddingTop设置为30看一下效果:

    运行:

    如果此时将paddingTop设置成负值呢?

    编译运行:

    那隐藏头部视图的思路就有啦:让这个paddingTop变成负具体头部视图的高度不就可以了么,那如何获得具体差部视图的高度呢?根据经验目前是在View的初始化阶段:

    此时并未对视图进行测量,所以直接获取selfHeaderView的测量高度肯定是获取不到滴,那要想获得测量高度则需要提前测量,那如何搞呢?

    编译运行:

    这样就为之后的下拉刷新的效果做好了铺垫。

    头部管理器的处理【重构】:

    在继续往下实现之前,对咱们目前的代码进行一下小重构,为什么呢?还是为了适应未来的具体头部替换的需求,假如要换成美团的下拉刷新效果,头部势必要变,那看下如果要变,基于目前我们的代码这块就得动:

    很显然不符合开闭原则,为了应对未来会换具体头部的需求,应该将SelfHeaderView的逻辑单独出来,于是乎头部管理器类的设计应运而生了,所以下面对目前的代码进行调整一下:

    /**
     * 为了未来头部内容可以灵活进行切换,将其封装于此
     */
    public class SelfHeaderViewManager {
    
        private Context context;
        private View selfHeaderView;
    
        public SelfHeaderViewManager(Context context) {
            this.context = context;
        }
    
        public View getSelfHeaderView() {
            if (selfHeaderView == null) {
                selfHeaderView = View.inflate(context, R.layout.view_refresh_header_normal, null);
                selfHeaderView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            }
            return selfHeaderView;
        }
    }

    然后在RefreshLayout中实例化这个头部管理器,然后将selfHeaderView的获取通过管理器去拿,如下:

    /**
     * 下拉刷新控件
     * 头部管理器的处理
     */
    public class RefreshLayout extends LinearLayout {
    
        /* 头部根布局 */
        private LinearLayout wholeHeaderView;
    
        /* 具体头部管理器 */
        private SelfHeaderViewManager selfHeaderViewManager;
    
        /**
         * 设置自定义头部管理器
         */
        public void setSelfHeaderViewManager(SelfHeaderViewManager selfHeaderViewManager) {
            this.selfHeaderViewManager = selfHeaderViewManager;
            initSelfHeaderView();
        }
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.setOrientation(LinearLayout.VERTICAL);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    
        //初始化具体的头部内容
        private void initSelfHeaderView() {
            View selfHeaderView = selfHeaderViewManager.getSelfHeaderView();//此时处于视图的加载阶段,并未对视图进行测量,想要获取测量高度,需要提前测量
            selfHeaderView.measure(0, 0);
            int selfHeaderViewMeasuredHeight = selfHeaderView.getMeasuredHeight();
            //利用给头部根布局设置padding为负达到隐藏它里面子视图的效果
            wholeHeaderView.setPadding(0, -selfHeaderViewMeasuredHeight, 0, 0);
            wholeHeaderView.addView(selfHeaderView);
        }
    }

    而最新的管理器的提供暴露给Activity去提供,如下:

    有木有觉得这种写法有点像RecyclerView在初始化时也需要传入一个manager,如下:

    嗯,有那么一点意思,这样就将具体头部视图的获取从RefreshLayout中剥离开啦,另外还有一个小细节可以再小调一下,就是对于头部视图测量高度的获取,如下:

    所以说干就干:

    /**
     * 为了未来头部内容可以灵活进行切换,将其封装于此
     */
    public class SelfHeaderViewManager {
    
        private Context context;
        private View selfHeaderView;
    
        public SelfHeaderViewManager(Context context) {
            this.context = context;
        }
    
        public View getSelfHeaderView() {
            if (selfHeaderView == null) {
                selfHeaderView = View.inflate(context, R.layout.view_refresh_header_normal, null);
                selfHeaderView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            }
            return selfHeaderView;
        }
    
        public int getSelfHeaderViewHeight() {
            //此时处于视图的加载阶段,并未对视图进行测量,想要获取测量高度,需要提前测量
            selfHeaderView.measure(0, 0);
            return selfHeaderView.getMeasuredHeight();
        }
    
    }

    这时代码可扩展性就比较好了~

    定义边界:

    另外还需要做一个准备工作,就是需要定义出这两个边界值,如:

    为什么要定义出这两个边界,因为在之后的逻辑判断中会需要用到它,所以首先先定义最小的边界变量:

    /**
     * 下拉刷新控件
     * 定义边界
     */
    public class RefreshLayout extends LinearLayout {
    
        //views
        /* 头部根布局 */
        private LinearLayout wholeHeaderView;
    
        //variables
        /* 具体头部管理器 */
        private SelfHeaderViewManager selfHeaderViewManager;
        /* 头部视图的最大上边距,也就是默认需通过它来将头部隐藏掉 */
        private int minWholeHeaderViewPaddingTop;
    
        /**
         * 设置自定义头部管理器
         */
        public void setSelfHeaderViewManager(SelfHeaderViewManager selfHeaderViewManager) {
            this.selfHeaderViewManager = selfHeaderViewManager;
            initSelfHeaderView();
        }
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.setOrientation(LinearLayout.VERTICAL);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    
        //初始化具体的头部内容
        private void initSelfHeaderView() {
            View selfHeaderView = selfHeaderViewManager.getSelfHeaderView();
            int selfHeaderViewMeasuredHeight = this.selfHeaderViewManager.getSelfHeaderViewHeight();
            minWholeHeaderViewPaddingTop = -selfHeaderViewMeasuredHeight;
            //利用给头部根布局设置padding为负达到隐藏它里面子视图的效果
            wholeHeaderView.setPadding(0, minWholeHeaderViewPaddingTop, 0, 0);
            wholeHeaderView.addView(selfHeaderView);
        }
    }

    然后再再定义最大的头部边界,那最大边界定义成多少呢?这里用一个相对值,相对于具体头部View的测量高度多于30%【可根据具体需求来定义】,如下:

    /**
     * 下拉刷新控件
     * 定义边界
     */
    public class RefreshLayout extends LinearLayout {
        //constants
        /* 头部视图超出最大范围的系数 */
        public static final float MAX_WHOLE_HEADER_VIEW_PADDING_TOP_RADIO = 0.3f;
    
        //views
        /* 头部根布局 */
        private LinearLayout wholeHeaderView;
    
        //variables
        /* 具体头部管理器 */
        private SelfHeaderViewManager selfHeaderViewManager;
        /* 头部视图的最大上边距,也就是默认需通过它来将头部隐藏掉 */
        private int minWholeHeaderViewPaddingTop;
        /* 头部视图的最大上边距=头部视图的高度*头部视图超出最大范围的系数,也就是下拉头部显示高度的最大值 */
        private int maxWholeHeaderViewPaddingTop;
    
        /**
         * 设置自定义头部管理器
         */
        public void setSelfHeaderViewManager(SelfHeaderViewManager selfHeaderViewManager) {
            this.selfHeaderViewManager = selfHeaderViewManager;
            initSelfHeaderView();
        }
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.setOrientation(LinearLayout.VERTICAL);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    
        //初始化具体的头部内容
        private void initSelfHeaderView() {
            View selfHeaderView = selfHeaderViewManager.getSelfHeaderView();
            int selfHeaderViewMeasuredHeight = this.selfHeaderViewManager.getSelfHeaderViewHeight();
            minWholeHeaderViewPaddingTop = -selfHeaderViewMeasuredHeight;
            //最大边界定义为头部高度的30%
            maxWholeHeaderViewPaddingTop = (int) (selfHeaderViewMeasuredHeight * MAX_WHOLE_HEADER_VIEW_PADDING_TOP_RADIO);
            //利用给头部根布局设置padding为负达到隐藏它里面子视图的效果
            wholeHeaderView.setPadding(0, minWholeHeaderViewPaddingTop, 0, 0);
            wholeHeaderView.addView(selfHeaderView);
        }
    }

    写完代码了也得验证一下是否达到预期,这里对最大边界进行测试一下,先临时写死代码:

    编译运行:

    好了,这个边界条件的准备工作已经到位了,记得还是将测试代码还原。

    将头部拉出:

    有了前面的准备工作之后,接下来要实现的效果就是增加滑动事件处理,也就是随着手指向下滑动头部视图跟随着慢慢移动,先来整理一下思路:

    如果这时在滑到B点时,想让头部视图也往下移动,那么让头部视图的paddingTop = paddingTop + (B.y - A.y),其效果如下:

    所以可以按着这个思路来编写逻辑代码,当然首先得要处理触摸事件,如下:

    假如内容是一个ListView,那是所有的事件都交由咱们的RefreshLayout处理么?不一定,看这么一个情况:

    很明显,在加载过程中,事件是可以被列表处理的,所以这里先用默认的方式返回,具体啥时候返回true,啥时候返回false是需要根据业务逻辑来的:

    对于DOWN事件,很显示是需要由RefreshLayout处理,所以这里可以返回true,然后可以获取当前的y值:

    /**
     * 下拉刷新控件
     * 将头部拉出
     */
    public class RefreshLayout extends LinearLayout {
        //constants
        /* 头部视图超出最大范围的系数 */
        public static final float MAX_WHOLE_HEADER_VIEW_PADDING_TOP_RADIO = 0.3f;
    
        //views
        /* 头部根布局 */
        private LinearLayout wholeHeaderView;
    
        //variables
        /* 具体头部管理器 */
        private SelfHeaderViewManager selfHeaderViewManager;
        /* 头部视图的最大上边距,也就是默认需通过它来将头部隐藏掉 */
        private int minWholeHeaderViewPaddingTop;
        /* 头部视图的最大上边距=头部视图的高度*头部视图超出最大范围的系数,也就是下拉头部显示高度的最大值 */
        private int maxWholeHeaderViewPaddingTop;
        private int downY;
    
        /**
         * 设置自定义头部管理器
         */
        public void setSelfHeaderViewManager(SelfHeaderViewManager selfHeaderViewManager) {
            this.selfHeaderViewManager = selfHeaderViewManager;
            initSelfHeaderView();
        }
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.setOrientation(LinearLayout.VERTICAL);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    
        //初始化具体的头部内容
        private void initSelfHeaderView() {
            View selfHeaderView = selfHeaderViewManager.getSelfHeaderView();
            int selfHeaderViewMeasuredHeight = this.selfHeaderViewManager.getSelfHeaderViewHeight();
            minWholeHeaderViewPaddingTop = -selfHeaderViewMeasuredHeight;
            //最大边界定义为头部高度的30%
            maxWholeHeaderViewPaddingTop = (int) (selfHeaderViewMeasuredHeight * MAX_WHOLE_HEADER_VIEW_PADDING_TOP_RADIO);
            //利用给头部根布局设置padding为负达到隐藏它里面子视图的效果
            wholeHeaderView.setPadding(0, minWholeHeaderViewPaddingTop, 0, 0);
            wholeHeaderView.addView(selfHeaderView);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downY = (int) event.getY();
                    return true;
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return super.onTouchEvent(event);//注意:由于将来会套在ListView上面,所以这里不能一股脑的将它返回true
        }
    }

    接着处理MOVE事件,目前也是可以返回true,也获取当前的y,并算出距离DOWN时y之间的差值,不过之后会对逻辑进行修改:

    编译运行:

    呃,没有做最大边界判断,目前头部是无限可以往下扩大的,所以这里需要做一下边界判断,如下:

    再次编译运行:

    嗯~~完美~~不过还差一个小细节,现实的下拉刷新控件在下拉时会有一个弹簧效果,也就是越往下越难拉出,类似于阻尼效果,现在是均匀拉出的,目前的paddingTop是线性变化的,可以看下paddingTop的变化值:

    其输出如下:

    12-11 10:40:27.291 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-62
    12-11 10:40:27.307 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-61
    12-11 10:40:27.323 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-57
    12-11 10:40:27.339 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:40:27.359 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-56
    12-11 10:40:27.371 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:40:27.391 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:40:27.407 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 10:40:27.423 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 10:40:27.443 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 10:40:27.507 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 10:40:27.523 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 10:40:27.543 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 10:40:27.559 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-51
    12-11 10:40:27.575 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 10:40:27.599 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-11 10:40:27.623 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-45
    12-11 10:40:27.643 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:40:27.655 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 10:40:27.675 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-38
    12-11 10:40:27.691 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 10:40:27.707 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 10:40:27.723 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-11 10:40:27.743 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 10:40:27.759 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 10:40:27.775 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 10:40:27.791 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:40:27.823 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 10:40:27.839 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 10:40:27.859 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 10:40:27.875 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 10:40:27.891 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:40:27.907 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 10:40:27.923 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:-7
    12-11 10:40:27.959 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 10:40:27.975 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:2
    12-11 10:40:27.991 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:3
    12-11 10:40:28.007 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:4
    12-11 10:40:28.023 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:6
    12-11 10:40:28.039 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:7
    12-11 10:40:28.059 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:9
    12-11 10:40:28.075 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:10
    12-11 10:40:28.091 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:12
    12-11 10:40:28.107 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:12
    12-11 10:40:28.127 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:15
    12-11 10:40:28.147 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:15
    12-11 10:40:28.163 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:16
    12-11 10:40:28.175 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:17
    12-11 10:40:28.211 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:20
    12-11 10:40:28.227 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:20
    12-11 10:40:28.243 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:22
    12-11 10:40:28.255 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:23
    12-11 10:40:28.275 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:26
    12-11 10:40:28.291 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:40:28.307 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:32
    12-11 10:40:28.323 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:33
    12-11 10:40:28.343 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:35
    12-11 10:40:28.359 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:36
    12-11 10:40:28.375 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:38
    12-11 10:40:28.391 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:40
    12-11 10:40:28.407 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:41
    12-11 10:40:28.423 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:42
    12-11 10:40:28.439 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:44
    12-11 10:40:28.459 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:44
    12-11 10:40:28.475 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:45
    12-11 10:40:28.491 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:46
    12-11 10:40:28.507 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:48
    12-11 10:40:28.523 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:49
    12-11 10:40:28.543 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:51
    12-11 10:40:28.559 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:51
    12-11 10:40:28.575 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:52
    12-11 10:40:28.591 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:54
    12-11 10:40:28.607 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:55
    12-11 10:40:28.623 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:58
    12-11 10:40:28.639 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:58
    12-11 10:40:28.655 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:59
    12-11 10:40:28.675 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:61
    12-11 10:40:28.691 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:62
    12-11 10:40:28.707 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:64
    12-11 10:40:28.727 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:65
    12-11 10:40:28.743 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:67
    12-11 10:40:28.759 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:68
    12-11 10:40:28.775 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:70
    12-11 10:40:28.791 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:71
    12-11 10:40:28.807 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:71
    12-11 10:40:28.823 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:73
    12-11 10:40:28.839 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:74
    12-11 10:40:28.859 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:75
    12-11 10:40:28.875 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:75
    12-11 10:40:28.907 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:75
    12-11 10:40:29.007 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:77
    12-11 10:40:29.043 6796-6796/com.pulltorefresh.test E/cexo: paddingTop:77

    而解决思路就是不让它线性变化,怎么做可以不让它线性变化呢?让dy除以一个系数既可,如下:

    这时再看:

    可以看到越往下则滑动距离越大,其看下paddingTop的变化:

    12-11 10:44:27.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-62
    12-11 10:44:27.624 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-62
    12-11 10:44:27.640 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-61
    12-11 10:44:27.656 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-61
    12-11 10:44:27.676 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-60
    12-11 10:44:27.692 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-60
    12-11 10:44:27.708 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-59
    12-11 10:44:27.740 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-59
    12-11 10:44:27.756 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-59
    12-11 10:44:27.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-59
    12-11 10:44:27.808 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-57
    12-11 10:44:27.824 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-58
    12-11 10:44:27.840 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-57
    12-11 10:44:27.856 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-57
    12-11 10:44:27.876 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-57
    12-11 10:44:27.892 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-56
    12-11 10:44:27.908 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-56
    12-11 10:44:27.924 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:44:27.944 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:44:27.956 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:44:27.976 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 10:44:28.008 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-53
    12-11 10:44:28.024 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 10:44:28.040 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 10:44:28.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-53
    12-11 10:44:28.092 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-53
    12-11 10:44:28.108 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-51
    12-11 10:44:28.124 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 10:44:28.140 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 10:44:28.156 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-51
    12-11 10:44:28.176 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-51
    12-11 10:44:28.208 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 10:44:28.224 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 10:44:28.244 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 10:44:28.276 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 10:44:28.292 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 10:44:28.308 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 10:44:28.324 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 10:44:28.360 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-48
    12-11 10:44:28.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-48
    12-11 10:44:28.392 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-48
    12-11 10:44:28.428 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-11 10:44:28.440 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-11 10:44:28.460 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 10:44:28.492 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 10:44:28.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 10:44:28.524 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 10:44:28.556 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 10:44:28.576 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 10:44:28.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-11 10:44:28.640 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-45
    12-11 10:44:28.692 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-45
    12-11 10:44:28.724 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-11 10:44:28.740 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-11 10:44:28.772 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-11 10:44:28.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-43
    12-11 10:44:28.824 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-43
    12-11 10:44:28.840 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:44:28.860 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:44:28.892 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:44:28.908 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:44:28.956 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:44:28.992 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 10:44:29.040 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 10:44:29.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-41
    12-11 10:44:29.108 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-41
    12-11 10:44:29.124 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 10:44:29.172 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 10:44:29.208 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 10:44:29.292 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 10:44:29.340 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-39
    12-11 10:44:29.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-39
    12-11 10:44:29.440 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-39
    12-11 10:44:29.456 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-38
    12-11 10:44:29.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-39
    12-11 10:44:29.544 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-39
    12-11 10:44:29.556 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 10:44:29.576 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 10:44:29.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 10:44:29.624 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 10:44:29.640 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 10:44:29.656 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 10:44:29.692 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 10:44:29.708 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 10:44:29.724 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 10:44:29.740 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-11 10:44:29.756 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-11 10:44:29.776 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-11 10:44:29.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 10:44:29.808 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 10:44:29.824 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 10:44:29.840 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-33
    12-11 10:44:29.856 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 10:44:29.892 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 10:44:29.924 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 10:44:29.992 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-33
    12-11 10:44:30.040 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-33
    12-11 10:44:30.092 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 10:44:30.172 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 10:44:30.208 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 10:44:30.224 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-31
    12-11 10:44:30.256 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-31
    12-11 10:44:30.292 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-31
    12-11 10:44:30.308 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 10:44:30.324 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 10:44:30.360 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 10:44:30.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 10:44:30.392 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 10:44:30.428 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 10:44:30.440 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 10:44:30.460 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 10:44:30.476 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 10:44:30.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-28
    12-11 10:44:30.524 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 10:44:30.540 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 10:44:30.556 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 10:44:30.576 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 10:44:30.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:44:30.660 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:44:30.756 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:44:31.024 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:44:31.040 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:44:31.056 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 10:44:31.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-11 10:44:31.092 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-11 10:44:31.108 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-11 10:44:31.140 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-11 10:44:31.156 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-23
    12-11 10:44:31.172 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-22
    12-11 10:44:31.192 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-22
    12-11 10:44:31.208 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 10:44:31.240 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 10:44:31.256 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 10:44:31.276 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 10:44:31.292 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 10:44:31.324 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 10:44:31.392 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 10:44:31.692 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 10:44:31.708 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 10:44:31.740 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 10:44:31.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 10:44:31.824 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 10:44:31.876 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 10:44:31.908 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 10:44:31.940 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 10:44:31.956 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 10:44:31.976 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 10:44:32.008 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 10:44:32.044 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 10:44:32.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 10:44:32.092 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 10:44:32.124 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 10:44:32.160 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:44:32.172 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:44:32.224 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:44:32.272 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:44:32.292 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:44:32.340 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 10:44:32.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 10:44:32.408 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 10:44:32.424 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 10:44:32.456 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 10:44:32.476 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 10:44:32.492 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-11 10:44:32.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 10:44:32.524 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 10:44:32.540 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 10:44:32.576 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-11 10:44:32.592 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-11 10:44:32.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-11 10:44:32.640 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-11 10:44:32.676 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-11 10:44:32.708 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-8
    12-11 10:44:32.740 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-11 10:44:32.760 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-11 10:44:32.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-8
    12-11 10:44:32.808 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-8
    12-11 10:44:32.840 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-8
    12-11 10:44:32.856 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-6
    12-11 10:44:32.892 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-7
    12-11 10:44:32.924 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-7
    12-11 10:44:32.976 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-6
    12-11 10:44:33.008 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-6
    12-11 10:44:33.024 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-6
    12-11 10:44:33.056 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 10:44:33.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 10:44:33.108 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 10:44:33.124 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 10:44:33.140 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 10:44:33.156 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-4
    12-11 10:44:33.176 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-4
    12-11 10:44:33.192 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-3
    12-11 10:44:33.208 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-3
    12-11 10:44:33.224 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-2
    12-11 10:44:33.240 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-2
    12-11 10:44:33.256 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-2
    12-11 10:44:33.292 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 10:44:33.308 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 10:44:33.324 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 10:44:33.340 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 10:44:33.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 10:44:33.392 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 10:44:33.424 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 10:44:33.460 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 10:44:33.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 10:44:33.540 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 10:44:33.556 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:1
    12-11 10:44:33.576 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 10:44:33.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:1
    12-11 10:44:33.640 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:2
    12-11 10:44:33.660 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:2
    12-11 10:44:33.692 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:3
    12-11 10:44:33.724 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:3
    12-11 10:44:33.756 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:4
    12-11 10:44:33.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:3
    12-11 10:44:33.808 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:3
    12-11 10:44:33.840 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:4
    12-11 10:44:33.856 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:4
    12-11 10:44:33.908 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:4
    12-11 10:44:33.940 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:5
    12-11 10:44:33.976 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:5
    12-11 10:44:34.024 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:5
    12-11 10:44:34.060 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:6
    12-11 10:44:34.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:6
    12-11 10:44:34.092 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:6
    12-11 10:44:34.124 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:7
    12-11 10:44:34.140 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:7
    12-11 10:44:34.160 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:7
    12-11 10:44:34.176 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:8
    12-11 10:44:34.212 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:7
    12-11 10:44:34.224 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:7
    12-11 10:44:34.240 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:8
    12-11 10:44:34.264 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:8
    12-11 10:44:34.280 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:9
    12-11 10:44:34.308 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:9
    12-11 10:44:34.332 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:10
    12-11 10:44:34.360 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:11
    12-11 10:44:34.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:11
    12-11 10:44:34.392 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:12
    12-11 10:44:34.412 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:12
    12-11 10:44:34.428 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:12
    12-11 10:44:34.440 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:13
    12-11 10:44:34.476 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:12
    12-11 10:44:34.492 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:13
    12-11 10:44:34.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:13
    12-11 10:44:34.524 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:14
    12-11 10:44:34.544 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:14
    12-11 10:44:34.556 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:14
    12-11 10:44:34.572 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:14
    12-11 10:44:34.592 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:14
    12-11 10:44:34.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:14
    12-11 10:44:34.624 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:16
    12-11 10:44:34.640 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:16
    12-11 10:44:34.660 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:17
    12-11 10:44:34.672 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:16
    12-11 10:44:34.692 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:16
    12-11 10:44:34.724 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:17
    12-11 10:44:34.748 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:17
    12-11 10:44:34.756 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:18
    12-11 10:44:34.776 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:18
    12-11 10:44:34.792 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:18
    12-11 10:44:34.808 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:19
    12-11 10:44:34.824 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:19
    12-11 10:44:34.840 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:19
    12-11 10:44:34.876 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:19
    12-11 10:44:34.892 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:21
    12-11 10:44:34.908 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:21
    12-11 10:44:34.924 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:21
    12-11 10:44:34.940 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:21
    12-11 10:44:34.956 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:21
    12-11 10:44:34.976 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:22
    12-11 10:44:34.992 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:22
    12-11 10:44:35.024 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:22
    12-11 10:44:35.040 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:23
    12-11 10:44:35.056 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:23
    12-11 10:44:35.076 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:23
    12-11 10:44:35.108 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:24
    12-11 10:44:35.124 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:23
    12-11 10:44:35.156 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:23
    12-11 10:44:35.176 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:24
    12-11 10:44:35.208 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:24
    12-11 10:44:35.224 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:24
    12-11 10:44:35.244 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:24
    12-11 10:44:35.276 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:25
    12-11 10:44:35.308 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:25
    12-11 10:44:35.344 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:25
    12-11 10:44:35.356 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:27
    12-11 10:44:35.376 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:26
    12-11 10:44:35.392 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:26
    12-11 10:44:35.408 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:26
    12-11 10:44:35.424 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:27
    12-11 10:44:35.456 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:27
    12-11 10:44:35.476 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:44:35.492 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:44:35.508 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:44:35.524 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:44:35.540 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:44:35.560 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:28
    12-11 10:44:35.608 6919-6919/com.pulltorefresh.test E/cexo: paddingTop:29

    可以看到日志中有很多相同的数字,也就最直观的效果就是拉了几次才会动一次,越拉越难拉,当然对于这个阻尼效果的系数可以定义成常量,便于以后进行调节,如下:

    定义状态提高效率:

    接下来来看一下"下拉刷新"和"释放刷新"文本状态变化的处理,这两个状态的触发条件:当头部未完全显示则显示"下拉刷新",而如果拉出的高度超出头部测量高度时则显示"翻译刷新",具体这里就不演示了,而头部完全显示时,其paddingTop=0,可以写死值看一下:

    编译运行:

    so,那在move处理这可以打点日志来看一下是否可以动态去执行相应的状态转换逻辑,先确保条件木有问题,在写代码之前先将写死的测试值还原:

    编译运行:

    12-11 11:04:31.041 7194-7194/com.pulltorefresh.test E/cexo: dY:2
    12-11 11:04:31.041 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-62
    12-11 11:04:31.041 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.057 7194-7194/com.pulltorefresh.test E/cexo: dY:4
    12-11 11:04:31.057 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-61
    12-11 11:04:31.057 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.077 7194-7194/com.pulltorefresh.test E/cexo: dY:6
    12-11 11:04:31.077 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-60
    12-11 11:04:31.077 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.093 7194-7194/com.pulltorefresh.test E/cexo: dY:8
    12-11 11:04:31.093 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-59
    12-11 11:04:31.093 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.109 7194-7194/com.pulltorefresh.test E/cexo: dY:7
    12-11 11:04:31.109 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-60
    12-11 11:04:31.109 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.125 7194-7194/com.pulltorefresh.test E/cexo: dY:8
    12-11 11:04:31.125 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-59
    12-11 11:04:31.125 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.145 7194-7194/com.pulltorefresh.test E/cexo: dY:10
    12-11 11:04:31.145 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-58
    12-11 11:04:31.145 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.181 7194-7194/com.pulltorefresh.test E/cexo: dY:12
    12-11 11:04:31.181 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-57
    12-11 11:04:31.181 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.193 7194-7194/com.pulltorefresh.test E/cexo: dY:13
    12-11 11:04:31.193 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-56
    12-11 11:04:31.193 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.217 7194-7194/com.pulltorefresh.test E/cexo: dY:14
    12-11 11:04:31.217 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-56
    12-11 11:04:31.217 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.245 7194-7194/com.pulltorefresh.test E/cexo: dY:16
    12-11 11:04:31.245 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-55
    12-11 11:04:31.245 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.273 7194-7194/com.pulltorefresh.test E/cexo: dY:17
    12-11 11:04:31.273 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 11:04:31.273 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.309 7194-7194/com.pulltorefresh.test E/cexo: dY:18
    12-11 11:04:31.309 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-54
    12-11 11:04:31.309 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.333 7194-7194/com.pulltorefresh.test E/cexo: dY:20
    12-11 11:04:31.333 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 11:04:31.333 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.353 7194-7194/com.pulltorefresh.test E/cexo: dY:20
    12-11 11:04:31.357 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 11:04:31.357 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.369 7194-7194/com.pulltorefresh.test E/cexo: dY:21
    12-11 11:04:31.369 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 11:04:31.369 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.377 7194-7194/com.pulltorefresh.test E/cexo: dY:21
    12-11 11:04:31.377 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 11:04:31.377 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.393 7194-7194/com.pulltorefresh.test E/cexo: dY:21
    12-11 11:04:31.393 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-52
    12-11 11:04:31.393 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.409 7194-7194/com.pulltorefresh.test E/cexo: dY:24
    12-11 11:04:31.409 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 11:04:31.409 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.425 7194-7194/com.pulltorefresh.test E/cexo: dY:23
    12-11 11:04:31.425 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-51
    12-11 11:04:31.425 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.441 7194-7194/com.pulltorefresh.test E/cexo: dY:24
    12-11 11:04:31.441 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 11:04:31.441 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.461 7194-7194/com.pulltorefresh.test E/cexo: dY:24
    12-11 11:04:31.461 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 11:04:31.461 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.473 7194-7194/com.pulltorefresh.test E/cexo: dY:24
    12-11 11:04:31.477 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-50
    12-11 11:04:31.477 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.493 7194-7194/com.pulltorefresh.test E/cexo: dY:27
    12-11 11:04:31.493 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 11:04:31.493 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.509 7194-7194/com.pulltorefresh.test E/cexo: dY:26
    12-11 11:04:31.509 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 11:04:31.509 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.525 7194-7194/com.pulltorefresh.test E/cexo: dY:26
    12-11 11:04:31.525 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 11:04:31.525 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.541 7194-7194/com.pulltorefresh.test E/cexo: dY:27
    12-11 11:04:31.541 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 11:04:31.541 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.557 7194-7194/com.pulltorefresh.test E/cexo: dY:27
    12-11 11:04:31.557 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-49
    12-11 11:04:31.557 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.573 7194-7194/com.pulltorefresh.test E/cexo: dY:29
    12-11 11:04:31.573 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-11 11:04:31.577 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.593 7194-7194/com.pulltorefresh.test E/cexo: dY:30
    12-11 11:04:31.593 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-11 11:04:31.593 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.609 7194-7194/com.pulltorefresh.test E/cexo: dY:30
    12-11 11:04:31.609 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-11 11:04:31.609 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.625 7194-7194/com.pulltorefresh.test E/cexo: dY:31
    12-11 11:04:31.625 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 11:04:31.625 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.641 7194-7194/com.pulltorefresh.test E/cexo: dY:31
    12-11 11:04:31.641 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-46
    12-11 11:04:31.641 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.661 7194-7194/com.pulltorefresh.test E/cexo: dY:33
    12-11 11:04:31.661 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-45
    12-11 11:04:31.661 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.673 7194-7194/com.pulltorefresh.test E/cexo: dY:33
    12-11 11:04:31.677 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-45
    12-11 11:04:31.677 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.693 7194-7194/com.pulltorefresh.test E/cexo: dY:35
    12-11 11:04:31.693 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-11 11:04:31.693 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.709 7194-7194/com.pulltorefresh.test E/cexo: dY:36
    12-11 11:04:31.709 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-11 11:04:31.709 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.725 7194-7194/com.pulltorefresh.test E/cexo: dY:37
    12-11 11:04:31.725 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-43
    12-11 11:04:31.725 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.741 7194-7194/com.pulltorefresh.test E/cexo: dY:39
    12-11 11:04:31.741 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-11 11:04:31.741 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.761 7194-7194/com.pulltorefresh.test E/cexo: dY:40
    12-11 11:04:31.761 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-41
    12-11 11:04:31.761 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.777 7194-7194/com.pulltorefresh.test E/cexo: dY:42
    12-11 11:04:31.777 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 11:04:31.777 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.793 7194-7194/com.pulltorefresh.test E/cexo: dY:43
    12-11 11:04:31.793 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 11:04:31.793 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.809 7194-7194/com.pulltorefresh.test E/cexo: dY:43
    12-11 11:04:31.809 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-11 11:04:31.809 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.825 7194-7194/com.pulltorefresh.test E/cexo: dY:45
    12-11 11:04:31.825 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-39
    12-11 11:04:31.825 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.845 7194-7194/com.pulltorefresh.test E/cexo: dY:46
    12-11 11:04:31.845 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-38
    12-11 11:04:31.845 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.857 7194-7194/com.pulltorefresh.test E/cexo: dY:46
    12-11 11:04:31.857 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-38
    12-11 11:04:31.857 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.877 7194-7194/com.pulltorefresh.test E/cexo: dY:47
    12-11 11:04:31.877 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 11:04:31.877 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.893 7194-7194/com.pulltorefresh.test E/cexo: dY:47
    12-11 11:04:31.893 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-11 11:04:31.893 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.909 7194-7194/com.pulltorefresh.test E/cexo: dY:49
    12-11 11:04:31.909 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 11:04:31.909 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.925 7194-7194/com.pulltorefresh.test E/cexo: dY:50
    12-11 11:04:31.925 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-36
    12-11 11:04:31.925 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.941 7194-7194/com.pulltorefresh.test E/cexo: dY:52
    12-11 11:04:31.941 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-11 11:04:31.941 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.957 7194-7194/com.pulltorefresh.test E/cexo: dY:52
    12-11 11:04:31.957 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-11 11:04:31.957 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.973 7194-7194/com.pulltorefresh.test E/cexo: dY:53
    12-11 11:04:31.977 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 11:04:31.977 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:31.993 7194-7194/com.pulltorefresh.test E/cexo: dY:53
    12-11 11:04:31.993 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-11 11:04:31.993 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.009 7194-7194/com.pulltorefresh.test E/cexo: dY:55
    12-11 11:04:32.009 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-33
    12-11 11:04:32.009 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.025 7194-7194/com.pulltorefresh.test E/cexo: dY:56
    12-11 11:04:32.025 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 11:04:32.025 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.041 7194-7194/com.pulltorefresh.test E/cexo: dY:56
    12-11 11:04:32.041 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-11 11:04:32.041 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.077 7194-7194/com.pulltorefresh.test E/cexo: dY:60
    12-11 11:04:32.077 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 11:04:32.077 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.093 7194-7194/com.pulltorefresh.test E/cexo: dY:59
    12-11 11:04:32.093 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-31
    12-11 11:04:32.093 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.109 7194-7194/com.pulltorefresh.test E/cexo: dY:60
    12-11 11:04:32.109 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-11 11:04:32.109 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.129 7194-7194/com.pulltorefresh.test E/cexo: dY:63
    12-11 11:04:32.129 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 11:04:32.129 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.141 7194-7194/com.pulltorefresh.test E/cexo: dY:62
    12-11 11:04:32.141 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 11:04:32.141 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.157 7194-7194/com.pulltorefresh.test E/cexo: dY:64
    12-11 11:04:32.157 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-28
    12-11 11:04:32.157 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.177 7194-7194/com.pulltorefresh.test E/cexo: dY:63
    12-11 11:04:32.177 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-11 11:04:32.177 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.193 7194-7194/com.pulltorefresh.test E/cexo: dY:65
    12-11 11:04:32.193 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 11:04:32.193 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.209 7194-7194/com.pulltorefresh.test E/cexo: dY:65
    12-11 11:04:32.209 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 11:04:32.209 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.225 7194-7194/com.pulltorefresh.test E/cexo: dY:66
    12-11 11:04:32.225 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 11:04:32.225 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.241 7194-7194/com.pulltorefresh.test E/cexo: dY:66
    12-11 11:04:32.241 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-11 11:04:32.241 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.261 7194-7194/com.pulltorefresh.test E/cexo: dY:69
    12-11 11:04:32.261 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-11 11:04:32.261 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.277 7194-7194/com.pulltorefresh.test E/cexo: dY:68
    12-11 11:04:32.277 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-11 11:04:32.277 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.293 7194-7194/com.pulltorefresh.test E/cexo: dY:69
    12-11 11:04:32.293 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-11 11:04:32.293 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.309 7194-7194/com.pulltorefresh.test E/cexo: dY:69
    12-11 11:04:32.309 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-11 11:04:32.309 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.329 7194-7194/com.pulltorefresh.test E/cexo: dY:72
    12-11 11:04:32.329 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-11 11:04:32.329 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.341 7194-7194/com.pulltorefresh.test E/cexo: dY:72
    12-11 11:04:32.341 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-11 11:04:32.341 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.357 7194-7194/com.pulltorefresh.test E/cexo: dY:73
    12-11 11:04:32.357 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-23
    12-11 11:04:32.357 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.377 7194-7194/com.pulltorefresh.test E/cexo: dY:72
    12-11 11:04:32.377 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-11 11:04:32.377 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.397 7194-7194/com.pulltorefresh.test E/cexo: dY:74
    12-11 11:04:32.397 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-22
    12-11 11:04:32.397 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.409 7194-7194/com.pulltorefresh.test E/cexo: dY:73
    12-11 11:04:32.409 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-23
    12-11 11:04:32.409 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.425 7194-7194/com.pulltorefresh.test E/cexo: dY:76
    12-11 11:04:32.425 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 11:04:32.429 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.449 7194-7194/com.pulltorefresh.test E/cexo: dY:76
    12-11 11:04:32.449 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 11:04:32.449 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.457 7194-7194/com.pulltorefresh.test E/cexo: dY:77
    12-11 11:04:32.457 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 11:04:32.457 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.493 7194-7194/com.pulltorefresh.test E/cexo: dY:76
    12-11 11:04:32.493 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 11:04:32.493 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.525 7194-7194/com.pulltorefresh.test E/cexo: dY:76
    12-11 11:04:32.525 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-11 11:04:32.525 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.577 7194-7194/com.pulltorefresh.test E/cexo: dY:79
    12-11 11:04:32.577 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 11:04:32.577 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.609 7194-7194/com.pulltorefresh.test E/cexo: dY:78
    12-11 11:04:32.609 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 11:04:32.609 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.641 7194-7194/com.pulltorefresh.test E/cexo: dY:78
    12-11 11:04:32.641 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 11:04:32.641 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.693 7194-7194/com.pulltorefresh.test E/cexo: dY:80
    12-11 11:04:32.693 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 11:04:32.693 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.741 7194-7194/com.pulltorefresh.test E/cexo: dY:79
    12-11 11:04:32.741 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 11:04:32.741 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.777 7194-7194/com.pulltorefresh.test E/cexo: dY:79
    12-11 11:04:32.777 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-11 11:04:32.777 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.829 7194-7194/com.pulltorefresh.test E/cexo: dY:81
    12-11 11:04:32.829 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 11:04:32.829 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.893 7194-7194/com.pulltorefresh.test E/cexo: dY:81
    12-11 11:04:32.893 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 11:04:32.893 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:32.957 7194-7194/com.pulltorefresh.test E/cexo: dY:81
    12-11 11:04:32.957 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-11 11:04:32.957 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.009 7194-7194/com.pulltorefresh.test E/cexo: dY:82
    12-11 11:04:33.009 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-18
    12-11 11:04:33.009 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.077 7194-7194/com.pulltorefresh.test E/cexo: dY:82
    12-11 11:04:33.077 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-18
    12-11 11:04:33.077 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.125 7194-7194/com.pulltorefresh.test E/cexo: dY:82
    12-11 11:04:33.125 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-18
    12-11 11:04:33.125 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.157 7194-7194/com.pulltorefresh.test E/cexo: dY:84
    12-11 11:04:33.157 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 11:04:33.157 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.193 7194-7194/com.pulltorefresh.test E/cexo: dY:84
    12-11 11:04:33.193 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 11:04:33.193 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.225 7194-7194/com.pulltorefresh.test E/cexo: dY:84
    12-11 11:04:33.225 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-11 11:04:33.225 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.241 7194-7194/com.pulltorefresh.test E/cexo: dY:85
    12-11 11:04:33.241 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 11:04:33.241 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.277 7194-7194/com.pulltorefresh.test E/cexo: dY:85
    12-11 11:04:33.277 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 11:04:33.277 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.293 7194-7194/com.pulltorefresh.test E/cexo: dY:85
    12-11 11:04:33.293 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-11 11:04:33.293 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.309 7194-7194/com.pulltorefresh.test E/cexo: dY:88
    12-11 11:04:33.309 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 11:04:33.309 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.325 7194-7194/com.pulltorefresh.test E/cexo: dY:87
    12-11 11:04:33.325 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 11:04:33.325 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.345 7194-7194/com.pulltorefresh.test E/cexo: dY:87
    12-11 11:04:33.345 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 11:04:33.345 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.361 7194-7194/com.pulltorefresh.test E/cexo: dY:88
    12-11 11:04:33.361 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 11:04:33.361 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.377 7194-7194/com.pulltorefresh.test E/cexo: dY:88
    12-11 11:04:33.377 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 11:04:33.377 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.393 7194-7194/com.pulltorefresh.test E/cexo: dY:88
    12-11 11:04:33.393 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-11 11:04:33.393 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.425 7194-7194/com.pulltorefresh.test E/cexo: dY:89
    12-11 11:04:33.425 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 11:04:33.425 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.441 7194-7194/com.pulltorefresh.test E/cexo: dY:89
    12-11 11:04:33.441 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 11:04:33.441 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.461 7194-7194/com.pulltorefresh.test E/cexo: dY:89
    12-11 11:04:33.461 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-14
    12-11 11:04:33.461 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.477 7194-7194/com.pulltorefresh.test E/cexo: dY:92
    12-11 11:04:33.477 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 11:04:33.477 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.493 7194-7194/com.pulltorefresh.test E/cexo: dY:91
    12-11 11:04:33.493 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-13
    12-11 11:04:33.493 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.509 7194-7194/com.pulltorefresh.test E/cexo: dY:91
    12-11 11:04:33.509 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-13
    12-11 11:04:33.509 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.525 7194-7194/com.pulltorefresh.test E/cexo: dY:93
    12-11 11:04:33.525 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 11:04:33.525 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.541 7194-7194/com.pulltorefresh.test E/cexo: dY:92
    12-11 11:04:33.541 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 11:04:33.541 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.557 7194-7194/com.pulltorefresh.test E/cexo: dY:92
    12-11 11:04:33.557 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-12
    12-11 11:04:33.557 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.577 7194-7194/com.pulltorefresh.test E/cexo: dY:95
    12-11 11:04:33.577 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 11:04:33.577 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.593 7194-7194/com.pulltorefresh.test E/cexo: dY:94
    12-11 11:04:33.593 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 11:04:33.593 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.609 7194-7194/com.pulltorefresh.test E/cexo: dY:94
    12-11 11:04:33.609 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 11:04:33.609 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.625 7194-7194/com.pulltorefresh.test E/cexo: dY:95
    12-11 11:04:33.629 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 11:04:33.629 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.641 7194-7194/com.pulltorefresh.test E/cexo: dY:95
    12-11 11:04:33.641 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 11:04:33.641 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.657 7194-7194/com.pulltorefresh.test E/cexo: dY:95
    12-11 11:04:33.657 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-11 11:04:33.657 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.677 7194-7194/com.pulltorefresh.test E/cexo: dY:98
    12-11 11:04:33.677 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-11 11:04:33.677 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.693 7194-7194/com.pulltorefresh.test E/cexo: dY:97
    12-11 11:04:33.693 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-11 11:04:33.693 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.709 7194-7194/com.pulltorefresh.test E/cexo: dY:99
    12-11 11:04:33.709 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-11 11:04:33.709 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.725 7194-7194/com.pulltorefresh.test E/cexo: dY:98
    12-11 11:04:33.725 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-11 11:04:33.725 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.741 7194-7194/com.pulltorefresh.test E/cexo: dY:100
    12-11 11:04:33.741 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-8
    12-11 11:04:33.741 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.761 7194-7194/com.pulltorefresh.test E/cexo: dY:100
    12-11 11:04:33.761 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-8
    12-11 11:04:33.761 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.777 7194-7194/com.pulltorefresh.test E/cexo: dY:102
    12-11 11:04:33.777 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-7
    12-11 11:04:33.777 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.793 7194-7194/com.pulltorefresh.test E/cexo: dY:101
    12-11 11:04:33.793 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-7
    12-11 11:04:33.793 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.809 7194-7194/com.pulltorefresh.test E/cexo: dY:105
    12-11 11:04:33.809 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 11:04:33.809 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.829 7194-7194/com.pulltorefresh.test E/cexo: dY:105
    12-11 11:04:33.829 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-11 11:04:33.829 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.845 7194-7194/com.pulltorefresh.test E/cexo: dY:107
    12-11 11:04:33.845 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-4
    12-11 11:04:33.845 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.873 7194-7194/com.pulltorefresh.test E/cexo: dY:108
    12-11 11:04:33.873 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-4
    12-11 11:04:33.873 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.901 7194-7194/com.pulltorefresh.test E/cexo: dY:110
    12-11 11:04:33.901 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-2
    12-11 11:04:33.901 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.917 7194-7194/com.pulltorefresh.test E/cexo: dY:111
    12-11 11:04:33.917 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-2
    12-11 11:04:33.917 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.937 7194-7194/com.pulltorefresh.test E/cexo: dY:112
    12-11 11:04:33.937 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 11:04:33.937 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.953 7194-7194/com.pulltorefresh.test E/cexo: dY:113
    12-11 11:04:33.953 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-11 11:04:33.953 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为下拉刷新
    12-11 11:04:33.969 7194-7194/com.pulltorefresh.test E/cexo: dY:114
    12-11 11:04:33.969 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 11:04:33.969 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:33.977 7194-7194/com.pulltorefresh.test E/cexo: dY:117
    12-11 11:04:33.977 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:1
    12-11 11:04:33.977 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:33.993 7194-7194/com.pulltorefresh.test E/cexo: dY:116
    12-11 11:04:33.993 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 11:04:33.993 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.017 7194-7194/com.pulltorefresh.test E/cexo: dY:116
    12-11 11:04:34.017 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:0
    12-11 11:04:34.017 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.037 7194-7194/com.pulltorefresh.test E/cexo: dY:117
    12-11 11:04:34.037 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:1
    12-11 11:04:34.037 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.061 7194-7194/com.pulltorefresh.test E/cexo: dY:119
    12-11 11:04:34.061 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:2
    12-11 11:04:34.061 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.089 7194-7194/com.pulltorefresh.test E/cexo: dY:118
    12-11 11:04:34.089 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:1
    12-11 11:04:34.089 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.109 7194-7194/com.pulltorefresh.test E/cexo: dY:119
    12-11 11:04:34.109 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:2
    12-11 11:04:34.109 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.129 7194-7194/com.pulltorefresh.test E/cexo: dY:120
    12-11 11:04:34.129 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:2
    12-11 11:04:34.129 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.153 7194-7194/com.pulltorefresh.test E/cexo: dY:121
    12-11 11:04:34.153 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:3
    12-11 11:04:34.153 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新
    12-11 11:04:34.177 7194-7194/com.pulltorefresh.test E/cexo: dY:123
    12-11 11:04:34.177 7194-7194/com.pulltorefresh.test E/cexo: paddingTop:4
    12-11 11:04:34.177 7194-7194/com.pulltorefresh.test E/cexo: 改变文字为释放刷新

    嗯~~条件木问题,但是!!发现一个性能问题:

    同样的,释放刷新也有同样的问题:

    目前是纯日志对于性能体现不是很明显,但如果这里面有大段的逻辑那就非常明显了,于是乎如标题有说需要定义一些状态来提高程序的效率,对于状态用枚举定义是最合适不过的啦,有几种状态呢?直接给出代码,有注释比较好理解:

    所以这就需要定义一个字段用来记录当前RefreshLayout的状态:

    然后在MOVE文字状态改变那块加入当前状态的判断,具体如下:

    编译运行:

    这样代码效率也会较高~

    文字和箭头随状态改变:

    接下来就真正处理上一步中的状态变化,这里将状态变化的逻辑处理封装到一个方法中集中管理,如下:

    接着就是对不同的状态进行界面上的逻辑处理了,想一下不同的头部其处理逻辑是不一样的,目前是只需要改变文字和箭头,那如果是美团的头部呢其处理又不是一样的,所以说对于这具体的状态处理应该转由咱们的selfHeaderViewManager来处理,于是乎每个状态对应一个方法,如下:

    /**
     * 为了未来头部内容可以灵活进行切换,将其封装于此
     * 做状态刷新
     */
    public class SelfHeaderViewManager {
    
        private Context context;
        private View selfHeaderView;
    
        public SelfHeaderViewManager(Context context) {
            this.context = context;
        }
    
        public View getSelfHeaderView() {
            if (selfHeaderView == null) {
                selfHeaderView = View.inflate(context, R.layout.view_refresh_header_normal, null);
                selfHeaderView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            }
            return selfHeaderView;
        }
    
        public int getSelfHeaderViewHeight() {
            //此时处于视图的加载阶段,并未对视图进行测量,想要获取测量高度,需要提前测量
            selfHeaderView.measure(0, 0);
            return selfHeaderView.getMeasuredHeight();
        }
    
        public void changeToIdle() {
            //TODO
        }
    
        public void changeToPullDown() {
            //TODO
        }
    
        public void changeToReleaseRefresh() {
            //TODO
        }
    
        public void changeToRefreshing() {
            //TODO
        }
    }

    然后这时先对头部的文字提示做下状态处理,如下:

    public class SelfHeaderViewManager {
    
        private Context context;
    
        private View selfHeaderView;
        /* 提示文本 */
        private TextView tv_normal_refresh_header_status;
    
        public SelfHeaderViewManager(Context context) {
            this.context = context;
        }
    
        public View getSelfHeaderView() {
            if (selfHeaderView == null) {
                selfHeaderView = View.inflate(context, R.layout.view_refresh_header_normal, null);
                selfHeaderView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                tv_normal_refresh_header_status = selfHeaderView.findViewById(R.id.tv_normal_refresh_header_status);
            }
            return selfHeaderView;
        }
    
        public int getSelfHeaderViewHeight() {
            //此时处于视图的加载阶段,并未对视图进行测量,想要获取测量高度,需要提前测量
            selfHeaderView.measure(0, 0);
            return selfHeaderView.getMeasuredHeight();
        }
    
        public void changeToIdle() {
            //TODO
        }
    
        public void changeToPullDown() {
            tv_normal_refresh_header_status.setText("下拉刷新");
        }
    
        public void changeToReleaseRefresh() {
            tv_normal_refresh_header_status.setText("释放刷新");
        }
    
        public void changeToRefreshing() {
            //TODO
        }
    }

    编译运行:

    接下来处理箭头的动画,在下拉刷新时箭头是顺时针旋转为向下方向,而到了释放刷新时则箭头是逆时针旋转为向上方向,所以说先实例化两个动画:

    public class SelfHeaderViewManager {
    
        private Context context;
        /* 箭头旋转向上动画 */
        private RotateAnimation upAnimation;
        /* 箭头旋转向下动画 */
        private RotateAnimation downAnimation;
    
        private View selfHeaderView;
        /* 提示文本 */
        private TextView tv_normal_refresh_header_status;
    
        public SelfHeaderViewManager(Context context) {
            this.context = context;
            initAnimation();
        }
    
        private void initAnimation() {
            upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            upAnimation.setDuration(100);
            //动画执行完成后不会回到原点
            upAnimation.setFillAfter(true);
    
            downAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            downAnimation.setDuration(100);
            //动画执行完成后不会回到原点
            downAnimation.setFillAfter(true);
        }
    
        public View getSelfHeaderView() {
            if (selfHeaderView == null) {
                selfHeaderView = View.inflate(context, R.layout.view_refresh_header_normal, null);
                selfHeaderView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                tv_normal_refresh_header_status = selfHeaderView.findViewById(R.id.tv_normal_refresh_header_status);
            }
            return selfHeaderView;
        }
    
        public int getSelfHeaderViewHeight() {
            //此时处于视图的加载阶段,并未对视图进行测量,想要获取测量高度,需要提前测量
            selfHeaderView.measure(0, 0);
            return selfHeaderView.getMeasuredHeight();
        }
    
        public void changeToIdle() {
            //TODO
        }
    
        public void changeToPullDown() {
            tv_normal_refresh_header_status.setText("下拉刷新");
        }
    
        public void changeToReleaseRefresh() {
            tv_normal_refresh_header_status.setText("释放刷新");
        }
    
        public void changeToRefreshing() {
            //TODO
        }
    }

    然后在指定状态中去让箭头View执行对应的动画:

    编译运行:

    抬起手后隐藏头部:

    接下来处理UP事件了,首先处理何时消费UP事件的问题,从效果中可以看到只要是拉出头部,UP事件就应该由当前RefreshLayout处理,而其它情况是不需要处理UP事件的,所以类似MOVE事件,也将UP事件的逻辑封装到一个方法中处理:

    接下来具体处理UP,得分两种情况,一是下拉刷新状态时UP应该是让头部缩回去,二是释放刷新状态时UP应该是进行刷新中的状态,这里先只处理第一种情况,具体处理如下:

    这时在UP隐藏头部时应该从当前拉出的头部位置执行一段动画将它隐藏有一段时间,这时ValueAnimator就派上用场了,之前也已经用过了,具体写法如下:

    编译看下效果:

    抬起手后从释放刷新进入刷新中状态:

    接着处理UP的另外一种状态-刷新中,逻辑也比较简单,直接上代码:

     接着得继续完头部beginRefreshing方法,首先应该是先将头部从拉出的位置回到正常头部的状态,也就是回到头部测量高度,这时跟上一步骤的动画效果类似:

    最后还需要根据当前刷新中的状态对头部视图进行更新,更新为:文字是"刷新中..."、Loading代替箭头,所以这个处理当然是在SelfHeaderViewManager进行啦,如下:

    /**
     * 为了未来头部内容可以灵活进行切换,将其封装于此
     * 抬起手后从释放刷新进入刷新中状态
     */
    public class SelfHeaderViewManager {
    
        private Context context;
        /* 箭头旋转向上动画 */
        private RotateAnimation upAnimation;
        /* 箭头旋转向下动画 */
        private RotateAnimation downAnimation;
        /* Loading动画 */
        private AnimationDrawable animationDrawable;
    
        private View selfHeaderView;
        /* 提示文本 */
        private TextView tv_normal_refresh_header_status;
        /* 箭头 */
        private ImageView iv_normal_refresh_header_arrow;
        /* loadingView */
        private ImageView iv_normal_refresh_header_loading;
    
        public SelfHeaderViewManager(Context context) {
            this.context = context;
            initAnimation();
        }
    
        private void initAnimation() {
            upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            upAnimation.setDuration(100);
            //动画执行完成后不会回到原点
            upAnimation.setFillAfter(true);
    
            downAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            downAnimation.setDuration(100);
            //动画执行完成后不会回到原点
            downAnimation.setFillAfter(true);
        }
    
        public View getSelfHeaderView() {
            if (selfHeaderView == null) {
                selfHeaderView = View.inflate(context, R.layout.view_refresh_header_normal, null);
                selfHeaderView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                tv_normal_refresh_header_status = selfHeaderView.findViewById(R.id.tv_normal_refresh_header_status);
                iv_normal_refresh_header_arrow = selfHeaderView.findViewById(R.id.iv_normal_refresh_header_arrow);
                iv_normal_refresh_header_loading = selfHeaderView.findViewById(R.id.iv_normal_refresh_header_loading);
                animationDrawable = (AnimationDrawable) iv_normal_refresh_header_loading.getDrawable();
            }
            return selfHeaderView;
        }
    
        public int getSelfHeaderViewHeight() {
            //此时处于视图的加载阶段,并未对视图进行测量,想要获取测量高度,需要提前测量
            selfHeaderView.measure(0, 0);
            return selfHeaderView.getMeasuredHeight();
        }
    
        public void changeToIdle() {
            //TODO
        }
    
        public void changeToPullDown() {
            tv_normal_refresh_header_status.setText("下拉刷新");
            iv_normal_refresh_header_arrow.startAnimation(downAnimation);
        }
    
        public void changeToReleaseRefresh() {
            tv_normal_refresh_header_status.setText("释放刷新");
            iv_normal_refresh_header_arrow.startAnimation(upAnimation);
        }
    
        public void changeToRefreshing() {
            tv_normal_refresh_header_status.setText("加载中...");
            iv_normal_refresh_header_arrow.setVisibility(View.INVISIBLE);
            iv_normal_refresh_header_loading.setVisibility(View.VISIBLE);
            animationDrawable.start();
        }
    }

    编译运行:

    呃~~貌似看到一个bug,为啥松手之后箭头木有隐藏呢?这里不卖关子了,是由于箭头view之前是执行过动画,对于执行过动画的View想要隐藏之前需要先将动画清除,所以这个需要注意,解决如下:

    再次编译运行:

    从刷新中还原到初始状态:

    最后再来处理刷新完之后的状态,在完成最后一个状态之前,先来解决一个bug,先演示下:

    居然在刷新中状态中头部还可以随手指滑动,正常在刷新状态中是不允许再响应滑动事件啦,所以解决起来也so easy,加个条件判断:

    编译运行:

    接着来处理刷新结束之后的状态,那问题来了,什么时候刷新结束呢?很显然这应该是由调用方去确定,比如请求网络,而对于咱们这个demo而言应该是由Activity来决定何时刷新完,所以RefreshLayout应该往外甩刷新回调出来,然后Activity在刷新回调中进行具体刷新逻辑,于是乎:

    /**
     * 下拉刷新控件
     * 从刷新中还原到初始状态
     */
    public class RefreshLayout extends LinearLayout {
        //constants
        /* 头部视图超出最大范围的系数 */
        public static final float MAX_WHOLE_HEADER_VIEW_PADDING_TOP_RADIO = 0.3f;
        /* 阻尼效果的拉出系数 */
        public static final float DRAG_RADIO = 1.8f;
    
        /* 刷新状态 */
        public enum RefreshStatus {
            IDLE/*静止*/, PULL_DOWN/*下拉*/, RELEASE_REFRESH/*释放刷新*/, REFRESHING/*刷新*/
        }
    
        //views
        /* 头部根布局 */
        private LinearLayout wholeHeaderView;
    
        //variables
        /* 具体头部管理器 */
        private SelfHeaderViewManager selfHeaderViewManager;
        /* 头部视图的最大上边距,也就是默认需通过它来将头部隐藏掉 */
        private int minWholeHeaderViewPaddingTop;
        /* 头部视图的最大上边距=头部视图的高度*头部视图超出最大范围的系数,也就是下拉头部显示高度的最大值 */
        private int maxWholeHeaderViewPaddingTop;
        private int downY;
        private RefreshLayout.RefreshStatus currentStatus = RefreshLayout.RefreshStatus.IDLE;
        /* 刷新回调监听 */
        private RefreshLayout.OnRefreshingListener onRefreshingListener;
    
        public void setOnRefreshingListener(RefreshLayout.OnRefreshingListener onRefreshingListener) {
            this.onRefreshingListener = onRefreshingListener;
        }
        
        /**
         * 设置自定义头部管理器
         */
        public void setSelfHeaderViewManager(SelfHeaderViewManager selfHeaderViewManager) {
            this.selfHeaderViewManager = selfHeaderViewManager;
            initSelfHeaderView();
        }
    
        public RefreshLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            this.setOrientation(LinearLayout.VERTICAL);
            init();
        }
    
        private void init() {
            //1、初始化头部的视图
            initWholeHeaderView();
        }
    
        private void initWholeHeaderView() {
            //动态添加一个头部的根部局,以便未来可以动态更换头部:比如上下箭头效果、美团效果等
            wholeHeaderView = new LinearLayout(getContext());
            wholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            wholeHeaderView.setBackgroundColor(Color.parseColor("#FF4081"));
            addView(wholeHeaderView);
        }
    
        //初始化具体的头部内容
        private void initSelfHeaderView() {
            View selfHeaderView = selfHeaderViewManager.getSelfHeaderView();
            int selfHeaderViewMeasuredHeight = this.selfHeaderViewManager.getSelfHeaderViewHeight();
            minWholeHeaderViewPaddingTop = -selfHeaderViewMeasuredHeight;
            //最大边界定义为头部高度的30%
            maxWholeHeaderViewPaddingTop = (int) (selfHeaderViewMeasuredHeight * MAX_WHOLE_HEADER_VIEW_PADDING_TOP_RADIO);
            //利用给头部根布局设置padding为负达到隐藏它里面子视图的效果
            wholeHeaderView.setPadding(0, minWholeHeaderViewPaddingTop, 0, 0);
            wholeHeaderView.addView(selfHeaderView);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downY = (int) event.getY();
                    return true;
                case MotionEvent.ACTION_MOVE:
                    if (handleActionMove(event))
                        return true;
                    break;
                case MotionEvent.ACTION_UP:
                    if (handleActionUp(event))
                        return true;
                    break;
            }
            return super.onTouchEvent(event);//注意:由于将来会套在ListView上面,所以这里不能一股脑的将它返回true
        }
    
        private boolean handleActionMove(MotionEvent event) {
            if (currentStatus == RefreshLayout.RefreshStatus.REFRESHING)//如果是刷新状态了,则不允许移动了
                return false;
            int moveY = (int) event.getY();
            int dY = moveY - downY;
            Log.e("cexo", "dY:" + dY);
            //只有向下移动才能拉出头部
            if (dY > 0) {
    //            int paddingTop = minWholeHeaderViewPaddingTop + dY;
                //阻尼效果:就是类似弹簧的效果,随距离越来越长,拉动越来越难,让dy除以一个系数,不让它是线性变化
                int paddingTop = (int) (minWholeHeaderViewPaddingTop + dY / DRAG_RADIO);
                Log.e("cexo", "paddingTop:" + paddingTop);
                if (paddingTop < 0 && currentStatus != RefreshLayout.RefreshStatus.PULL_DOWN) {
                    currentStatus = RefreshLayout.RefreshStatus.PULL_DOWN;
                    //改变文字为下拉刷新
                    handleRefreshStatusChanged();
                } else if (paddingTop >= 0 && currentStatus != RefreshLayout.RefreshStatus.RELEASE_REFRESH) {
                    currentStatus = RefreshLayout.RefreshStatus.RELEASE_REFRESH;
                    //改变文字为释放刷新,并箭头进行旋转
                    handleRefreshStatusChanged();
                }
                //判断如果paddingTop>maxWholeHeaderViewPaddingTop,就不能再滑动了
                paddingTop = Math.min(paddingTop, maxWholeHeaderViewPaddingTop);
                wholeHeaderView.setPadding(0, paddingTop, 0, 0);
                return true;
            }
            return false;
        }
    
        private boolean handleActionUp(MotionEvent event) {
            if (currentStatus == RefreshLayout.RefreshStatus.PULL_DOWN) {
                //如果是下拉刷新状态则松开手时直接让头部隐藏
                hiddenRefreshView();
                currentStatus = RefreshLayout.RefreshStatus.IDLE;
                //如果换为美团下拉刷新等,当头部回到初始状态时需要做一些还原操作
                handleRefreshStatusChanged();
            } else if (currentStatus == RefreshLayout.RefreshStatus.RELEASE_REFRESH) {
                beginRefreshing();
            }
            //只要将头部拉出一点点UP事件就由当前控件处理
            return wholeHeaderView.getPaddingTop() > minWholeHeaderViewPaddingTop;
        }
    
        private void hiddenRefreshView() {
            ValueAnimator valueAnimator = ValueAnimator.ofInt(wholeHeaderView.getPaddingTop(), minWholeHeaderViewPaddingTop);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    //获取值动画在动画变化过程中的值
                    int currentPaddingTop = (int) valueAnimator.getAnimatedValue();
                    wholeHeaderView.setPadding(0, currentPaddingTop, 0, 0);
                }
            });
            valueAnimator.setDuration(300);
            valueAnimator.start();
        }
    
        /**
         * 开始刷新
         */
        private void beginRefreshing() {
            currentStatus = RefreshLayout.RefreshStatus.REFRESHING;
            changeHeaderViewPaddingTopToZero();
            handleRefreshStatusChanged();
            if (onRefreshingListener != null)
                onRefreshingListener.onRefresh();
        }
    
        /**
         * 将头部的paddingTop改变为0,也就是还原成头部的高度
         */
        private void changeHeaderViewPaddingTopToZero() {
            ValueAnimator valueAnimator = ValueAnimator.ofInt(wholeHeaderView.getPaddingTop(), 0);
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    //获取值动画在动画变化过程中的值
                    int currentPaddingTop = (int) valueAnimator.getAnimatedValue();
                    wholeHeaderView.setPadding(0, currentPaddingTop, 0, 0);
                }
            });
            valueAnimator.setDuration(300);
            valueAnimator.start();
        }
    
        /**
         * 根据当前的下拉状态来做界面刷新,具体实现由manager处理
         */
        private void handleRefreshStatusChanged() {
            switch (currentStatus) {
                case IDLE:
                    selfHeaderViewManager.changeToIdle();
                    break;
                case PULL_DOWN:
                    selfHeaderViewManager.changeToPullDown();
                    break;
                case RELEASE_REFRESH:
                    selfHeaderViewManager.changeToReleaseRefresh();
                    break;
                case REFRESHING:
                    selfHeaderViewManager.changeToRefreshing();
                    break;
            }
        }
    
        public interface OnRefreshingListener {
            void onRefresh();
        }
    }

    然后在Activity去注册回调:

    然后当执行完刷新逻辑之后,RefreshLayout还应该给外面暴露结束刷新的方法,所以增加结束方法如下:

    这时在Activity简单做个延时来模拟刷新逻辑,如下:

    好了,看下最终效果:

    加入RecyclerView之后的事件处理:

    哎呀,终于到最后一步了,之前在重写onTouchEvent()事件时就说当内容是列表界面时会有滑动冲突问题,而实际下拉刷新基本上都是基于列表,所以接下来就专项来处理它,所以内容先加入RecyclerView并整些列表数据让它显示出来,由于之前在集成QQ汽泡时已经用到RecyclerView,所以这里直接上代码,不多解释:

    布局中定义:

    <?xml version="1.0" encoding="utf-8"?>
    <com.pulltorefresh.test.RefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/lay_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.pulltorefresh.test.MainActivity">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/lay_rlv"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </com.pulltorefresh.test.RefreshLayout>

    填充数据:

    //加入RecyclerView之后的事件处理
    public class MainActivity extends AppCompatActivity implements RefreshLayout.OnRefreshingListener {
    
        private RefreshLayout lay_refresh_layout;
        private RecyclerView lay_rlv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lay_refresh_layout = (RefreshLayout) findViewById(R.id.lay_refresh_layout);
            lay_refresh_layout.setSelfHeaderViewManager(new SelfHeaderViewManager(this));
            lay_refresh_layout.setOnRefreshingListener(this);
            initRecyclerView();
        }
    
        @Override
        public void onRefresh() {
            //获取网络数据
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    //当获取完数据后通知RefreshLayout还原
                    lay_refresh_layout.endRefreshing();
                }
            }, 2000);
        }
    
        private void initRecyclerView() {
            lay_rlv = (RecyclerView) findViewById(R.id.lay_rlv);
            lay_rlv.setLayoutManager(new LinearLayoutManager(this));
            List<String> datas = new ArrayList<>();
            for (int i = 0; i < 30; i++) {
                datas.add("条目" + i);
            }
            MainActivity.MyAdapter adapter = new MainActivity.MyAdapter(datas);
            lay_rlv.setAdapter(adapter);
        }
    
    
        private class MyAdapter extends RecyclerView.Adapter<MainActivity.MyAdapter.MyViewHolder> {
            private List<String> datas;
    
            public MyAdapter(List<String> datas) {
                this.datas = datas;
            }
    
            @Override
            public MainActivity.MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, null);//TODO
                return new MainActivity.MyAdapter.MyViewHolder(view);
            }
    
            @Override
            public void onBindViewHolder(MainActivity.MyAdapter.MyViewHolder holder, int position) {
                holder.tv.setText(datas.get(position));
            }
    
            @Override
            public int getItemCount() {
                return datas.size();
            }
    
            class MyViewHolder extends RecyclerView.ViewHolder {
                private TextView tv;
    
                public MyViewHolder(View itemView) {
                    super(itemView);
                    tv = (TextView) itemView.findViewById(android.R.id.text1);
                }
            }
        }
    }

    运行:

    嗯~列表是显示出来了,但是居然下拉拉不出头部了,首先冲突就暴露出来了,也是接下来要来征服它滴。

    这时要解释目前只有RecyclerView处理事件,而咱们的RefreshLayout却没能处理,这时就要加想一下咱们上次分析的事件分发的原理啦【http://www.cnblogs.com/webor2006/p/7860381.html】,可见掌握事件分发的原理是何等重要,这时先来分角色,很显示RefreshLayout可以看成孔融爷爷,而RecyclerView可以看成孔融爸爸,当这两个的onTouchEvent()都返回true,也就是都想处理事件时,最终会交给孩子,如:

    而此时如果父视图【RefreshLayout】想处理事件,可以重写onInterceptTouchEvent返回true来强迫事件自己处理,如:

    当然我们得分条件来处理onInterceptTouchEvent(),不过这里为了让咱们的RefreshLayout能获得事件,先一股脑的重写onInterceptTouchEvent()=true,看看效果:

    很显然事件全都由RefreshLayout处理啦,说明通过控制onInterceptTouchEvent()就可以达到某种条件下让RefreshLayout父视图处理,某种条件交由RecyclerView子视图处理,那问题来了,什么条件下RefreshLayout()的onInterceptTouchEvent()返回true呢?很显示粗略的观察,只要是向下滑动时,这时应该返回true,那对应逻辑应该怎么写呢?其也就是判断y滑动的距离是否大于x滑动的距离就可以了,在写代码之前记得将这个强行测试返回true的代码还原,如下:

    接下来运行一下:

    嗯,貌似是父子视图都可以处理事件了,但是还是存在bug的,首先先来看第一个bug:

    滑动一点点,居然头部就出来一大块,这明显是不对的,那如何查找原因呢?因为跟滑动用关,所以最好还是通过打印日志的方法来定位,于是乎在滑动处理方法中打如下日志:

    再次复现,并查看日志:

    继续打日志跟踪downY=0的异常原因:

    再次复现,看日志:

    呃~~居然没有走RefreshLayout.onTouchEvent()的DOWN事件,那是为啥呢?这时就得再次回忆咱们的事件分发啦,从源码来分析其原因:

    由于在RefreshLayout中的onInterceptTouchEvent()在DOWN并未返回true,也就是为false,如下:

    所以这会将事件分发给它的子视图去处理:

    这时再来看它的事件处理过程:

    这时事件再由里往外传递,最终发现爷爷的down事件并未传到它自身的onTouchEvent(),因为:

    这就从源码上来解释了这个问题,那如何解决目前没有走RefreshLayout的onTouchEvent()中的DOWN事件造成downY=0,其时在MOVE时发现downY=0时可以做个补救措施,因为第一个MOVE跟DOWN的位置几乎相邻,所以修改代码如下:

    编译运行:

    好了,这个BUG修复了,再来演示另外一个BUG,重头开始演示哈:

    也就是第一次DOWN木有问题可以正常拉出头部,但是如果第二次DOWN的位置在第一次DOWN位置上面就滑不出头部了,这具体是啥原因呢?看下刚才的日志输出:

    12-13 06:12:37.856 4328-4328/com.pulltorefresh.test E/cexo: dY:-160;moveY:201downY:361
    12-13 06:13:03.188 4328-4328/com.pulltorefresh.test E/cexo: dY:28;moveY:389downY:361
    12-13 06:13:03.188 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-48
    12-13 06:13:03.204 4328-4328/com.pulltorefresh.test E/cexo: dY:29;moveY:390downY:361
    12-13 06:13:03.204 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-13 06:13:03.224 4328-4328/com.pulltorefresh.test E/cexo: dY:30;moveY:391downY:361
    12-13 06:13:03.224 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-47
    12-13 06:13:03.236 4328-4328/com.pulltorefresh.test E/cexo: dY:34;moveY:395downY:361
    12-13 06:13:03.236 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-45
    12-13 06:13:03.252 4328-4328/com.pulltorefresh.test E/cexo: dY:36;moveY:397downY:361
    12-13 06:13:03.252 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-44
    12-13 06:13:03.272 4328-4328/com.pulltorefresh.test E/cexo: dY:39;moveY:400downY:361
    12-13 06:13:03.272 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-42
    12-13 06:13:03.288 4328-4328/com.pulltorefresh.test E/cexo: dY:41;moveY:402downY:361
    12-13 06:13:03.288 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-41
    12-13 06:13:03.308 4328-4328/com.pulltorefresh.test E/cexo: dY:43;moveY:404downY:361
    12-13 06:13:03.308 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-40
    12-13 06:13:03.324 4328-4328/com.pulltorefresh.test E/cexo: dY:46;moveY:407downY:361
    12-13 06:13:03.324 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-38
    12-13 06:13:03.340 4328-4328/com.pulltorefresh.test E/cexo: dY:48;moveY:409downY:361
    12-13 06:13:03.340 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-37
    12-13 06:13:03.356 4328-4328/com.pulltorefresh.test E/cexo: dY:51;moveY:412downY:361
    12-13 06:13:03.356 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-13 06:13:03.372 4328-4328/com.pulltorefresh.test E/cexo: dY:52;moveY:413downY:361
    12-13 06:13:03.372 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-35
    12-13 06:13:03.396 4328-4328/com.pulltorefresh.test E/cexo: dY:53;moveY:414downY:361
    12-13 06:13:03.396 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-34
    12-13 06:13:03.432 4328-4328/com.pulltorefresh.test E/cexo: dY:56;moveY:417downY:361
    12-13 06:13:03.432 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-13 06:13:03.456 4328-4328/com.pulltorefresh.test E/cexo: dY:56;moveY:417downY:361
    12-13 06:13:03.456 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-32
    12-13 06:13:03.468 4328-4328/com.pulltorefresh.test E/cexo: dY:58;moveY:419downY:361
    12-13 06:13:03.468 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-31
    12-13 06:13:03.484 4328-4328/com.pulltorefresh.test E/cexo: dY:59;moveY:420downY:361
    12-13 06:13:03.484 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-31
    12-13 06:13:03.496 4328-4328/com.pulltorefresh.test E/cexo: dY:61;moveY:422downY:361
    12-13 06:13:03.496 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-30
    12-13 06:13:03.504 4328-4328/com.pulltorefresh.test E/cexo: dY:62;moveY:423downY:361
    12-13 06:13:03.504 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-13 06:13:03.532 4328-4328/com.pulltorefresh.test E/cexo: dY:62;moveY:423downY:361
    12-13 06:13:03.532 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-13 06:13:03.536 4328-4328/com.pulltorefresh.test E/cexo: dY:63;moveY:424downY:361
    12-13 06:13:03.536 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-29
    12-13 06:13:03.552 4328-4328/com.pulltorefresh.test E/cexo: dY:65;moveY:426downY:361
    12-13 06:13:03.552 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-13 06:13:03.568 4328-4328/com.pulltorefresh.test E/cexo: dY:65;moveY:426downY:361
    12-13 06:13:03.568 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-13 06:13:03.588 4328-4328/com.pulltorefresh.test E/cexo: dY:66;moveY:427downY:361
    12-13 06:13:03.588 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-13 06:13:03.604 4328-4328/com.pulltorefresh.test E/cexo: dY:66;moveY:427downY:361
    12-13 06:13:03.604 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-27
    12-13 06:13:03.624 4328-4328/com.pulltorefresh.test E/cexo: dY:68;moveY:429downY:361
    12-13 06:13:03.624 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-26
    12-13 06:13:03.640 4328-4328/com.pulltorefresh.test E/cexo: dY:69;moveY:430downY:361
    12-13 06:13:03.640 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-25
    12-13 06:13:03.656 4328-4328/com.pulltorefresh.test E/cexo: dY:71;moveY:432downY:361
    12-13 06:13:03.656 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-13 06:13:03.672 4328-4328/com.pulltorefresh.test E/cexo: dY:71;moveY:432downY:361
    12-13 06:13:03.672 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-13 06:13:03.688 4328-4328/com.pulltorefresh.test E/cexo: dY:72;moveY:433downY:361
    12-13 06:13:03.688 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-24
    12-13 06:13:03.720 4328-4328/com.pulltorefresh.test E/cexo: dY:74;moveY:435downY:361
    12-13 06:13:03.720 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-22
    12-13 06:13:03.740 4328-4328/com.pulltorefresh.test E/cexo: dY:75;moveY:436downY:361
    12-13 06:13:03.740 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-22
    12-13 06:13:03.756 4328-4328/com.pulltorefresh.test E/cexo: dY:75;moveY:436downY:361
    12-13 06:13:03.756 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-22
    12-13 06:13:03.772 4328-4328/com.pulltorefresh.test E/cexo: dY:76;moveY:437downY:361
    12-13 06:13:03.772 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-21
    12-13 06:13:03.788 4328-4328/com.pulltorefresh.test E/cexo: dY:78;moveY:439downY:361
    12-13 06:13:03.788 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-13 06:13:03.808 4328-4328/com.pulltorefresh.test E/cexo: dY:78;moveY:439downY:361
    12-13 06:13:03.808 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-13 06:13:03.820 4328-4328/com.pulltorefresh.test E/cexo: dY:79;moveY:440downY:361
    12-13 06:13:03.820 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-20
    12-13 06:13:03.840 4328-4328/com.pulltorefresh.test E/cexo: dY:81;moveY:442downY:361
    12-13 06:13:03.840 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-19
    12-13 06:13:03.856 4328-4328/com.pulltorefresh.test E/cexo: dY:84;moveY:445downY:361
    12-13 06:13:03.856 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-17
    12-13 06:13:03.868 4328-4328/com.pulltorefresh.test E/cexo: dY:85;moveY:446downY:361
    12-13 06:13:03.868 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-16
    12-13 06:13:03.892 4328-4328/com.pulltorefresh.test E/cexo: dY:88;moveY:449downY:361
    12-13 06:13:03.892 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-15
    12-13 06:13:03.904 4328-4328/com.pulltorefresh.test E/cexo: dY:91;moveY:452downY:361
    12-13 06:13:03.904 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-13
    12-13 06:13:03.924 4328-4328/com.pulltorefresh.test E/cexo: dY:94;moveY:455downY:361
    12-13 06:13:03.924 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-11
    12-13 06:13:03.940 4328-4328/com.pulltorefresh.test E/cexo: dY:97;moveY:458downY:361
    12-13 06:13:03.940 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-10
    12-13 06:13:03.956 4328-4328/com.pulltorefresh.test E/cexo: dY:99;moveY:460downY:361
    12-13 06:13:03.956 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-9
    12-13 06:13:03.972 4328-4328/com.pulltorefresh.test E/cexo: dY:103;moveY:464downY:361
    12-13 06:13:03.972 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-6
    12-13 06:13:03.984 4328-4328/com.pulltorefresh.test E/cexo: dY:105;moveY:466downY:361
    12-13 06:13:03.984 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-5
    12-13 06:13:04.004 4328-4328/com.pulltorefresh.test E/cexo: dY:108;moveY:469downY:361
    12-13 06:13:04.004 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-4
    12-13 06:13:04.024 4328-4328/com.pulltorefresh.test E/cexo: dY:109;moveY:470downY:361
    12-13 06:13:04.024 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-3
    12-13 06:13:04.040 4328-4328/com.pulltorefresh.test E/cexo: dY:112;moveY:473downY:361
    12-13 06:13:04.040 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:-1
    12-13 06:13:04.056 4328-4328/com.pulltorefresh.test E/cexo: dY:114;moveY:475downY:361
    12-13 06:13:04.056 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:0
    12-13 06:13:04.088 4328-4328/com.pulltorefresh.test E/cexo: dY:117;moveY:478downY:361
    12-13 06:13:04.088 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:1
    12-13 06:13:04.108 4328-4328/com.pulltorefresh.test E/cexo: dY:118;moveY:479downY:361
    12-13 06:13:04.108 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:1
    12-13 06:13:04.140 4328-4328/com.pulltorefresh.test E/cexo: dY:121;moveY:482downY:361
    12-13 06:13:04.140 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:3
    12-13 06:13:04.172 4328-4328/com.pulltorefresh.test E/cexo: dY:122;moveY:483downY:361
    12-13 06:13:04.172 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:3
    12-13 06:13:04.188 4328-4328/com.pulltorefresh.test E/cexo: dY:124;moveY:485downY:361
    12-13 06:13:04.188 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:4
    12-13 06:13:04.212 4328-4328/com.pulltorefresh.test E/cexo: dY:125;moveY:486downY:361
    12-13 06:13:04.212 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:5
    12-13 06:13:04.252 4328-4328/com.pulltorefresh.test E/cexo: dY:127;moveY:488downY:361
    12-13 06:13:04.252 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:6
    12-13 06:13:04.272 4328-4328/com.pulltorefresh.test E/cexo: dY:128;moveY:489downY:361
    12-13 06:13:04.272 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:7
    12-13 06:13:04.300 4328-4328/com.pulltorefresh.test E/cexo: dY:130;moveY:491downY:361
    12-13 06:13:04.300 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:8
    12-13 06:13:04.308 4328-4328/com.pulltorefresh.test E/cexo: dY:130;moveY:491downY:361
    12-13 06:13:04.308 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:8
    12-13 06:13:04.320 4328-4328/com.pulltorefresh.test E/cexo: dY:131;moveY:492downY:361
    12-13 06:13:04.320 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:8
    12-13 06:13:04.340 4328-4328/com.pulltorefresh.test E/cexo: dY:132;moveY:493downY:361
    12-13 06:13:04.340 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:9
    12-13 06:13:04.352 4328-4328/com.pulltorefresh.test E/cexo: dY:132;moveY:493downY:361
    12-13 06:13:04.352 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:9
    12-13 06:13:04.372 4328-4328/com.pulltorefresh.test E/cexo: dY:135;moveY:496downY:361
    12-13 06:13:04.372 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:11
    12-13 06:13:04.388 4328-4328/com.pulltorefresh.test E/cexo: dY:137;moveY:498downY:361
    12-13 06:13:04.388 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:12
    12-13 06:13:04.404 4328-4328/com.pulltorefresh.test E/cexo: dY:137;moveY:498downY:361
    12-13 06:13:04.404 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:12
    12-13 06:13:04.420 4328-4328/com.pulltorefresh.test E/cexo: dY:138;moveY:499downY:361
    12-13 06:13:04.420 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:12
    12-13 06:13:04.440 4328-4328/com.pulltorefresh.test E/cexo: dY:140;moveY:501downY:361
    12-13 06:13:04.440 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:13
    12-13 06:13:04.456 4328-4328/com.pulltorefresh.test E/cexo: dY:140;moveY:501downY:361
    12-13 06:13:04.456 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:13
    12-13 06:13:04.488 4328-4328/com.pulltorefresh.test E/cexo: dY:140;moveY:501downY:361
    12-13 06:13:04.488 4328-4328/com.pulltorefresh.test E/cexo: paddingTop:13
    12-13 06:13:08.040 4328-4328/com.pulltorefresh.test E/cexo: dY:-196;moveY:165downY:361
    12-13 06:13:08.056 4328-4328/com.pulltorefresh.test E/cexo: dY:-192;moveY:169downY:361
    12-13 06:13:08.072 4328-4328/com.pulltorefresh.test E/cexo: dY:-188;moveY:173downY:361
    12-13 06:13:08.088 4328-4328/com.pulltorefresh.test E/cexo: dY:-184;moveY:177downY:361
    12-13 06:13:08.104 4328-4328/com.pulltorefresh.test E/cexo: dY:-179;moveY:182downY:361
    12-13 06:13:08.120 4328-4328/com.pulltorefresh.test E/cexo: dY:-174;moveY:187downY:361
    12-13 06:13:08.140 4328-4328/com.pulltorefresh.test E/cexo: dY:-169;moveY:192downY:361
    12-13 06:13:08.156 4328-4328/com.pulltorefresh.test E/cexo: dY:-165;moveY:196downY:361
    12-13 06:13:08.172 4328-4328/com.pulltorefresh.test E/cexo: dY:-162;moveY:199downY:361
    12-13 06:13:08.188 4328-4328/com.pulltorefresh.test E/cexo: dY:-161;moveY:200downY:361
    12-13 06:13:08.208 4328-4328/com.pulltorefresh.test E/cexo: dY:-159;moveY:202downY:361
    12-13 06:13:08.224 4328-4328/com.pulltorefresh.test E/cexo: dY:-158;moveY:203downY:361
    12-13 06:13:08.240 4328-4328/com.pulltorefresh.test E/cexo: dY:-156;moveY:205downY:361
    12-13 06:13:08.256 4328-4328/com.pulltorefresh.test E/cexo: dY:-155;moveY:206downY:361
    12-13 06:13:08.272 4328-4328/com.pulltorefresh.test E/cexo: dY:-153;moveY:208downY:361
    12-13 06:13:08.288 4328-4328/com.pulltorefresh.test E/cexo: dY:-153;moveY:208downY:361
    12-13 06:13:08.308 4328-4328/com.pulltorefresh.test E/cexo: dY:-151;moveY:210downY:361
    12-13 06:13:08.324 4328-4328/com.pulltorefresh.test E/cexo: dY:-152;moveY:209downY:361
    12-13 06:13:10.840 4328-4328/com.pulltorefresh.test E/cexo: dY:-231;moveY:130downY:361
    12-13 06:13:10.856 4328-4328/com.pulltorefresh.test E/cexo: dY:-225;moveY:136downY:361
    12-13 06:13:10.872 4328-4328/com.pulltorefresh.test E/cexo: dY:-218;moveY:143downY:361
    12-13 06:13:10.888 4328-4328/com.pulltorefresh.test E/cexo: dY:-214;moveY:147downY:361
    12-13 06:13:10.904 4328-4328/com.pulltorefresh.test E/cexo: dY:-207;moveY:154downY:361
    12-13 06:13:10.924 4328-4328/com.pulltorefresh.test E/cexo: dY:-203;moveY:158downY:361
    12-13 06:13:10.940 4328-4328/com.pulltorefresh.test E/cexo: dY:-198;moveY:163downY:361
    12-13 06:13:10.956 4328-4328/com.pulltorefresh.test E/cexo: dY:-194;moveY:167downY:361
    12-13 06:13:10.972 4328-4328/com.pulltorefresh.test E/cexo: dY:-190;moveY:171downY:361
    12-13 06:13:10.984 4328-4328/com.pulltorefresh.test E/cexo: dY:-187;moveY:174downY:361
    12-13 06:13:11.004 4328-4328/com.pulltorefresh.test E/cexo: dY:-185;moveY:176downY:361
    12-13 06:13:11.024 4328-4328/com.pulltorefresh.test E/cexo: dY:-182;moveY:179downY:361
    12-13 06:13:11.040 4328-4328/com.pulltorefresh.test E/cexo: dY:-179;moveY:182downY:361
    12-13 06:13:11.056 4328-4328/com.pulltorefresh.test E/cexo: dY:-178;moveY:183downY:361
    12-13 06:13:11.072 4328-4328/com.pulltorefresh.test E/cexo: dY:-176;moveY:185downY:361
    12-13 06:13:11.092 4328-4328/com.pulltorefresh.test E/cexo: dY:-172;moveY:189downY:361
    12-13 06:13:11.104 4328-4328/com.pulltorefresh.test E/cexo: dY:-173;moveY:188downY:361
    12-13 06:13:11.124 4328-4328/com.pulltorefresh.test E/cexo: dY:-171;moveY:190downY:361
    12-13 06:13:11.140 4328-4328/com.pulltorefresh.test E/cexo: dY:-171;moveY:190downY:361
    12-13 06:13:11.156 4328-4328/com.pulltorefresh.test E/cexo: dY:-171;moveY:190downY:361

    看这标红的第二次DOWN的日志输出,居然dy<0,造成它小于0的原因是由于moveY<downY,而downY的值居然一直是第一次DOWN时记录的位置,那这是为啥呢?还是由于跟上次补救downY的那句代码有关:

    这时要解决这个问题也比较简单,在UP的时候将downY清零既可,如下:

    这时再运行:

    嗯~~成功又解掉了一个BUG,不过~~BUG不断,再来演示一下:

    正常向下滑动时只有列表处于第一位时才能拉出头部,现在是不管是第向位都可以拉出头部,所时这时需要判断是否列表已经滑到最底端了,这时需要借助一个工具类,如下:

    public class RefreshScrollingUtil {
    
        private RefreshScrollingUtil() {
        }
    
    
        public static boolean isScrollViewOrWebViewToTop(View view) {
            return view != null && view.getScrollY() == 0;
        }
    
        public static boolean isAbsListViewToTop(AbsListView absListView) {
            if (absListView != null) {
                int firstChildTop = 0;
                if (absListView.getChildCount() > 0) {
                    // 如果AdapterView的子控件数量不为0,获取第一个子控件的top
                    firstChildTop = absListView.getChildAt(0).getTop() - absListView.getPaddingTop();
                }
                if (absListView.getFirstVisiblePosition() == 0 && firstChildTop == 0) {
                    return true;
                }
            }
            return false;
        }
    
        public static boolean isRecyclerViewToTop(RecyclerView recyclerView) {
            if (recyclerView != null) {
                RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
                if (manager == null) {
                    return true;
                }
                if (manager.getItemCount() == 0) {
                    return true;
                }
    
                if (manager instanceof LinearLayoutManager) {
                    LinearLayoutManager layoutManager = (LinearLayoutManager) manager;
    
                    int firstChildTop = 0;
                    if (recyclerView.getChildCount() > 0) {
                        // 处理item高度超过一屏幕时的情况
                        View firstVisibleChild = recyclerView.getChildAt(0);
                        if (firstVisibleChild != null && firstVisibleChild.getMeasuredHeight() >= recyclerView.getMeasuredHeight()) {
                            if (android.os.Build.VERSION.SDK_INT < 14) {
                                return !(ViewCompat.canScrollVertically(recyclerView, -1) || recyclerView.getScrollY() > 0);
                            } else {
                                return !ViewCompat.canScrollVertically(recyclerView, -1);
                            }
                        }
    
                        // 如果RecyclerView的子控件数量不为0,获取第一个子控件的top
    
                        // 解决item的topMargin不为0时不能触发下拉刷新
                        View firstChild = recyclerView.getChildAt(0);
                        RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) firstChild.getLayoutParams();
                        firstChildTop = firstChild.getTop() - layoutParams.topMargin - getRecyclerViewItemTopInset(layoutParams) - recyclerView.getPaddingTop();
                    }
    
                    if (layoutManager.findFirstCompletelyVisibleItemPosition() < 1 && firstChildTop == 0) {
                        return true;
                    }
                } else if (manager instanceof StaggeredGridLayoutManager) {
                    StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) manager;
    
                    int[] out = layoutManager.findFirstCompletelyVisibleItemPositions(null);
                    if (out[0] < 1) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        /**
         * 通过反射获取RecyclerView的item的topInset
         *
         * @param layoutParams
         * @return
         */
        private static int getRecyclerViewItemTopInset(RecyclerView.LayoutParams layoutParams) {
            try {
                Field field = RecyclerView.LayoutParams.class.getDeclaredField("mDecorInsets");
                field.setAccessible(true);
                // 开发者自定义的滚动监听器
                Rect decorInsets = (Rect) field.get(layoutParams);
                return decorInsets.top;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return 0;
        }
    
    
    
    }

    里面包含几种控件判断是否在顶端的方法,其中标红的是既是咱们需要用到的判断是否RecyclerView到顶端的方法,于是乎在onInterceptTouchEvent()的MOVE事件中增加该条件判断,如下:

    这时可以采用在onFinishInflate()来获取,因为它是在当前视图以及它的子视图都加载完成之后会回调它,所以直接获取RefreshLayout的第二个孩子既可recyclerView,第一个孩子是咱们事先添加的头部视图,所以代码如下:

    这时再运行:

    终于完美了~~篇幅巨长~~需好好消化~~

  • 相关阅读:
    HTML+CSS简单实现导航栏二级下拉菜单
    原创 | 我的个人微信公众号
    原创 | 喂,在吗?
    NodeJs实现邮箱验证
    JS排序算法(二)冒泡排序
    JS排序算法(一) 快速排序
    前端常见的布局方式
    JS继承方式
    前端Node实现简易的文件上传下载
    原生js实现深度克隆
  • 原文地址:https://www.cnblogs.com/webor2006/p/7989766.html
Copyright © 2011-2022 走看看