Android ListView 下拉刷新,上拉加载更多,带动画 自定义控件

原创 2016年08月29日 16:37:11

之前每次 项目中用到ListView 的 下拉刷新 以及上拉分页加载 都是 用的 网上 下载 的 类库,

使用起来 诸多不便 ,于是 趁着有空 ,自己封装了ListView 让其 实现 下拉刷新,以及分页加载功能。

以下是 效果图:

当 滑动到 ListView 顶部 或 尾部 时,再次手指上拉或下拉 则会 触发 ListView 的 刷新 ,并 显示 刷新 动画,完成后动画会 缓慢消失。



Demo 下载 地址:点击打开链接

具体 实现原理:

首先对 ListView 要设置 OnScrollListener 监听 其 滑动 状态 ,并 记录此 状态。

ListView的 滑动 状态 有 三种

	静止状态,SCROLL_STATE_IDLE
	手指滚动状态,SCROLL_STATE_TOUCH_SCROLL
	手指不动了,但是屏幕还在滚动状态。SCROLL_STATE_FLING

上下拉刷新 时 ListView的 滚动状态 必须为 手指滚动才触发刷新。


还要 对 ListView 设置 触摸 监听。

判断 ListView 的 滑动 方向,计算其 手指拖动距离,以及手指抬起时的 刷新动画的 状态

以下是 ListView 的 触摸 和 滚动 监听 代码

首先 在 滚动 监听 了 记录 当前 的 滚动状态。

然后 在 触摸监听里  当状态 为 Action.Move 移动 时,判断滚动的 方向,以及 ListView 当前位置 处于顶部还是底部,并且 是否正在刷新。

然后 根据 手指 移动的 距离 除以相应倍数 ,让 刷新动画 控件 缓慢 出现。 在Action.Up 中 判断 当前的 刷新控件 显示 的 高度 是否 触发 刷新 方法。


    int currentScorllState;

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        currentScorllState = scrollState;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
    }

    boolean rememberFreshYTag = true;
    float freshY;
    float tempY;
    int times = 3;
    boolean downTag = false;
    float y;

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        y = motionEvent.getY();
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float scrollHeight = y - tempY;
                if (scrollHeight > 0) {
                    downTag = true;
                } else {
                    downTag = false;
                }
                if (currentScorllState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL
                        && this.getFirstVisiblePosition() == 0
                        && this.getTop() == 0
                        && downTag
                        && !freshingTag
                        ) {
                    topFreshTag = true;
                    if (rememberFreshYTag) {
                        freshY = y;
                    }
                    rememberFreshYTag = false;

                    float min = Math.min(headHeight + headHeight / 2, (y - freshY) / times);
                    imageViewHead.setPadding(0, (int) (-headHeight + min), 0, 0);
                    Log.i("testss", "topFresh" + y);
                } else if (currentScorllState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL
                        && this.getLastVisiblePosition() == getCount() - 1
                        && this.getBottom() == this.getHeight()
                        && !downTag
                        && !freshingTag
                        ) {
                    bottomFreshTag = true;
                    if (rememberFreshYTag) {
                        freshY = y;
                    }
                    rememberFreshYTag = false;
                    float min = Math.min(footHeight + footHeight / 2, -(y - freshY));
                    imageViewFoot.setPadding(0, 0, 0, (int) (-footHeight + min));

                    Log.i("testss", "buttomFresh" + y + "---" + freshY);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (topFreshTag && !freshingTag) {
                    Log.i("testss", "uptopFreshTag");
                    // 手指 抬起时 符合 条件 则 触发 顶部刷新
                    judgeToFresh(TOP_FRESH, imageViewHead, headHeight);
                }
                if (bottomFreshTag && !freshingTag) {
//                    Log.i("testss", "upbottomFreshTag");
                    // 手指 抬起时 符合 条件 则 触发 底部刷新
                    judgeToFresh(BOTTOM_FRESH, imageViewFoot, footHeight);
                }
                break;
        }
        tempY = y;
        return super.onTouchEvent(motionEvent);
    }



以下 是判断 是否 刷新的方法

 /**
     * 判断 是否 触发 刷新
     *
     * @param freshType 刷新 的类型 顶部刷新 或 底部刷新
     * @param imageView 刷新动画 的 控件
     * @param height    当前 刷新动画 控件 显示 的 高度
     */
    private void judgeToFresh(int freshType, ImageView imageView, int height) {

        int paddingHeight = freshType == TOP_FRESH ? imageView.getPaddingTop() : imageView.getPaddingBottom();
        if (paddingHeight == height / 2) {
            imageView.setPadding(0, 0, 0, 0);
            freshingTag = true;
            if (freshType == TOP_FRESH) {
                onTopFresh();
            } else {
                onBottomFresh();
            }
        } else {
            dissHeadOrFootView(imageView, freshType, -paddingHeight, height);
        }
    }

    /**
     * 开始 顶部 刷新
     */
    private void onTopFresh() {
        // 开启 动画
        startOrStopAnimation(imageViewHead, true);
        /**
         * 如果 设置 了外部 监听
         * 则 调用 外部监听 的 刷新 方法
         * 否则 过1s后 自动完成 刷新动画
         */
        if (onListViewFreshListener == null) {
            tempHandler.sendEmptyMessageDelayed(TOP_FRESH, 1000);
        } else {
            onListViewFreshListener.onTopFreshing();
        }
    }

    /**
     * 开始 底部 刷新
     */
    private void onBottomFresh() {
        // 开启 动画
        startOrStopAnimation(imageViewFoot, true);
        /**
         * 如果 设置 了外部 监听
         * 则 调用 外部监听 的 刷新 方法
         * 否则 过1s后 自动完成 刷新动画
         */
        if (onListViewFreshListener == null) {
            tempHandler.sendEmptyMessageDelayed(BOTTOM_FRESH, 1000);
        } else {
            onListViewFreshListener.onBottomFreshing();
        }
    }




Demo 下载 地址:点击打开链接


版权声明:本文为博主原创文章,未经博主允许不得转载。

ZrcListView:一个流畅又漂亮的Android下拉刷新与加载更多列表组件

http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/0712/1632.html ZrcListView根据系统自带List...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

实现下拉刷新,上拉加载可自定义各种动画

优雅的实现RecyclerView的各种动画的下拉刷新,上拉加载

Android自定义下拉刷新动画--仿百度外卖下拉刷新

好久没写博客了,小编之前一段时间一直在找工作,从天津来到了我们的大帝都,感觉还不错。好了废话不多说了,开始我们今天的主题吧。现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前...
  • lyhhj
  • lyhhj
  • 2016年04月11日 12:01
  • 17423

一步步实现带动画效果的下拉刷新

先看效果 分析 1.先要在listview的头部加上一个布局,布局中包含一个文本控件一个图片 2.这个图片控件会随着下拉的过程做一个缩放 3.整个下拉刷新过程分三步: 第一步:下拉未超过布...

Android自定义控件——ListView的下拉刷新与上拉加载

无疑,在Android开发中,ListView是使用非常频繁的控件之一,ListView提供一个列表的容易,允许我们以列表的形式将数据展示到界面上,但是Google给我们提供的原生ListView的控...

PullToRefresh修改上拉下拉加载动画

修改PullTuRefreshListView源码: 实现 动画加载:第一步:源码分析:PullToRefrehListView 默认加载动画是很难看的: 默认是很难看的 但我们想要实...

自定义下拉刷新上拉加载动画

用的是Android-PullToRefresh,github上有,下载地址为https://github.com/chrisbanes/Android-PullToRefresh,其中simple为...

Android源码解析--超好看的下拉刷新动画

本篇博客代码下载地址:https://github.com/Yalantis/Taurus 最近在github上看到了好多高端、大气、上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定...
  • lyhhj
  • lyhhj
  • 2015年08月30日 20:09
  • 4445

Android 常用效果(各种进度条,酷炫loading动画,火箭升空,撒花以及趋势图)

最近时间比较充裕一些,总结了下几个项目用到的ui效果,在这边共享给大家,也给自己做个记录(后面会有demo贴出).  主要是以下几种ui效果: 进度条多种展示开源loading动画火箭升空撒花效果(...
  • jdsjlzx
  • jdsjlzx
  • 2015年08月31日 11:30
  • 15207
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android ListView 下拉刷新,上拉加载更多,带动画 自定义控件
举报原因:
原因补充:

(最多只允许输入30个字)