一、简介:
  下拉刷新是一种特定的手动刷新交互,和其他的同类操作不同的地方在于它采用了更加直觉的下拉操作,所以它的交互足够清晰明显。
下拉刷新主要用在类似ListView这样的控件,设计下拉刷新有三种方法:
  ① 使用SwipeRefreshLayout(没有在底部点击查看更多,需要自定义该功能), 常用的方法如下

1、setOnRefreshListener(OnRefreshListener listener)  设置下拉监听,当用户下拉的时候会去执行回调

2、setColorSchemeColors(int... colors) 设置 进度条的颜色变化,最多可以设置4种颜色

3、setProgressViewOffset(boolean scale, int start, int end) 调整进度条距离屏幕顶部的距离

4、setRefreshing(boolean refreshing) 设置SwipeRefreshLayout当前是否处于刷新状态,一般是在请求数据的时候设置为true,在数据被加载到View中后,设置为false。

  ②自定义控件,原理主要通过onTouchEvent中的ACTION_DOWN和ACTION_MOVE来计算触摸差值,再实现动画效果
  ③从github下载开源框架,直接使用,例如XListView
 
 
 
记得连接WIFi,查看网络图片超耗流量

 
 


 
 
  二、使用:
 
1、关于XUtils3(可以不用看它,重点是XListView) (https://github.com/wyouflf/xUtils3)
 
  主要作用: 请求网络、使用数据库、注解、绑定图片
 
先关联XUtils,compile project(':xutils')
设置权限 <uses-permission android:name="android.permission.INTERNET" />
             <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
初始化 创建一个 MyApplication继承自Application,在onCreate()方法内初始化下面两行代码(具体可参照github的例子)
   super.onCreate();
   x.Ext.init(this);
   x.Ext.setDebug(BuildConfig.DEBUG);// 是否输出debug日志, 开启debug会影响性能
 
在清单文件中必须配置 <application android:name="MyApplication" .../>   
 
因为图片是从网络上获取的,使用了请求网络,代码如下:
 x.http().get(new RequestParams(url), new Callback.CommonCallback<String>() {
 @Override
 public void onSuccess(String result) {
 imageListAdapter.addSrc(getImgSrcList(result));
 imageListAdapter.notifyDataSetChanged();//通知listview更新数据
 }

 @Override
 public void onError(Throwable ex, boolean isOnCallback) {

 }

 @Override
 public void onCancelled(CancelledException cex) {

 }

 @Override
 public void onFinished() {

 }
 });

绑定图片,代码如下:

 x.image().bind(holder.imgItem,
                     imgSrcList.get(position),
                     imageOptions,
                     new CustomBitmapLoadCallBack(holder));
 
2、关于XListView  (https://github.com/Maxwin-z/XListView-Android)
 
  主要作用:下拉刷新,上拉加载更多
XListView是一个自定控件,所以只需将它的源码直接用
  红色框内的需要拿来用
 
根据main.xml   可知<me.maxwin.view.XListView ......></me.maxwin.view.XListView> 所以需要把<ListView ..... />替换掉
根据XListViewActivity
 
......
mListView.setPullLoadEnable(true);
mListView.setXListViewListener(this);  //调用下面的接口IXListViewListener
......
public void setXListViewListener(IXListViewListener l) {
     mListViewListener = l;
}
.......
上面几行代码必须写上
/**
* implements this interface to get refresh/load more event.
*/
public interface IXListViewListener {
     public void onRefresh();

     public void onLoadMore();
}

三、XListView源码分析

public class XListView extends ListView implements OnScrollListener{
......

//上拉加载更多,将一些控件显示出来,例如ProgressBar,文本的设置,没什么好分析的,只分析下拉刷新

/**
* stop refresh, reset header view.
*/
public void stopRefresh() {
if (mPullRefreshing == true) {
mPullRefreshing = false;
resetHeaderHeight();
}
}
private void resetHeaderHeight() {
        //向下滑动的高度
        int height = mHeaderView.getVisiableHeight();
        if (height == 0) // 没滑动时,不做任何操作
            return;
        //滑动的高度小于header view's height,不做任何操作
        if (mPullRefreshing && height <= mHeaderViewHeight) {
            return;
        }
        int finalHeight = 0;  //若滑动后不做任何操作,值为0 否则为mHeaderViewHeight
        // 滑动的高度大于header view's height,设置finalHeight
        if (mPullRefreshing && height > mHeaderViewHeight) {
            finalHeight = mHeaderViewHeight;
        }
        mScrollBack = SCROLLBACK_HEADER;

        /**
         * 第一个参数是起始移动的x坐标值,第二个是起始移动的y坐标值
           第三及第四个参数都是移到某点的坐标值,duration 是执行移动的时间
         */
        mScroller.startScroll(0, height, 0, finalHeight - height,
                SCROLL_DURATION);

        //  触发computeScroll()
        /**
         * public void computeScroll ()
         Called by a parent to request that a child update its values for mScrollX and
         mScrollY if necessary. This will typically be done if the child is animating
         a scroll using a Scroller object.
         */
        //ontouch或invalidate()或postInvalidate()都会导致computeScroll()的执行
        invalidate();
    }


@Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mLastY == -1) {
            mLastY = ev.getRawY();
        }

        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //获取刚触碰的Y高度(原始的)
            mLastY = ev.getRawY();
            break;
        case MotionEvent.ACTION_MOVE:
            final float deltaY = ev.getRawY() - mLastY;
            mLastY = ev.getRawY();

            //getFirstVisiblePosition获取当前状态下list的第一个可见item的position
            //所以在listview中position总的加了1,获取准确的需要get(position - 1)
            if (getFirstVisiblePosition() == 0
                    && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {

                // 第一项是显示,下拉箭头显示或拉下来
                //类似于iOS下拉特性 deltaY / OFFSET_RADIO
                updateHeaderHeight(deltaY / OFFSET_RADIO);
                invokeOnScrolling();
            } else if (getLastVisiblePosition() == mTotalItemCount - 1
                    && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {
                // 最后一个item,上拉有效
                updateFooterHeight(-deltaY / OFFSET_RADIO);
            }
            break;
        default:
            mLastY = -1; // 重置
            if (getFirstVisiblePosition() == 0) {
                // 调用刷新
                if (mEnablePullRefresh
                        && mHeaderView.getVisiableHeight() > mHeaderViewHeight) {
                    mPullRefreshing = true;
                    mHeaderView.setState(XListViewHeader.STATE_REFRESHING);
                    if (mListViewListener != null) {
                        mListViewListener.onRefresh();
                    }
                }
                resetHeaderHeight();
            } else if (getLastVisiblePosition() == mTotalItemCount - 1) {
                // 调用加载更多
                if (mEnablePullLoad
                    && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA
                    && !mPullLoading) {
                    startLoadMore();
                }
                resetFooterHeight();
            }
            break;
        }
        return super.onTouchEvent(ev);
    }

// startScroll执行过程中即在duration时间内,computeScrollOffset  方法会一直返回false,但当动画执行完成后会返回返加true.

@Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            //如果执行过下拉刷新则 mScrollBack == SCROLLBACK_HEADER
            if (mScrollBack == SCROLLBACK_HEADER) {
                mHeaderView.setVisiableHeight(mScroller.getCurrY());
            } else {
                mFooterView.setBottomMargin(mScroller.getCurrY());
            }

            //类似于invalidate(),用于刷新view,主要在非UI线程中使用
            postInvalidate();
            //回滚监听
            invokeOnScrolling();
        }
        super.computeScroll();
    }

......
}

public class XListViewHeader extends LinearLayout { 
......

//旋转动画
        /**
         * RotateAnimation (float fromDegrees, float toDegrees, int pivotXType,
         * float pivotXValue, int pivotYType, float pivotYValue)
         参数说明:
         float fromDegrees:旋转的开始角度。
         float toDegrees:旋转的结束角度。
         int pivotXType:X轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
         float pivotXValue:X坐标的伸缩值。
         int pivotYType:Y轴的伸缩模式,可以取值为ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
         float pivotYValue:Y坐标的伸缩值。
         */
        mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        //设置动画持续时间
        mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
        //动画执行完后是否停留在执行完的状态
        mRotateUpAnim.setFillAfter(true);
        mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
        mRotateDownAnim.setFillAfter(true);


......

}
 
 

Android之XListView下拉刷新,更新网络美女图的更多相关文章

  1. Android 使用官方下拉刷新

    网上关于下拉刷新的文章也不少,不过都太长了,看得挺难受的.恰好发现了官方的下拉刷新库,而且效果还是不错的,简洁美观,用得也挺方便. 下面是效果图: 我的好友原来是空的,刷新后多了两个. 使用还是挺方便 ...

  2. Android XListView下拉刷新、上拉载入更多

    source code: https://github.com/Maxwin-z/XListView-Android 提供了两个接口: a) IXListViewListener:  触发下拉刷新.上 ...

  3. 【转载】Android中ListView下拉刷新的实现

    在网上看到一个下拉刷新的例子,很的很棒,转载和更多的人分享学习 原文:http://blog.csdn.net/loongggdroid/article/details/9385535 ListVie ...

  4. Android中ListView下拉刷新的实现

    ListView中的下拉刷新是非常常见的,也是经常使用的,看到有很多同学想要,那我就整理一下,供大家参考.那我就不解释,直接上代码了. 这里需要自己重写一下ListView,重写代码如下: packa ...

  5. Android中实现下拉刷新

    需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新: 思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息 ...

  6. Android之自定义控件-下拉刷新

    实现效果: 图片素材:         --> 首先, 写先下拉刷新时的刷新布局 pull_to_refresh.xml: <resources> <string name=& ...

  7. Android SwipeRefreshLayout 官方下拉刷新控件介绍

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24521483 下面App基本都有下拉刷新的功能,以前基本都使用XListView ...

  8. Android内置下拉刷新组件SwipeRefreshLayout

    也许下拉刷新之前,你可能会使用一些第三方的开源库,例如PullToRefresh, ActionBar-PullToRefresh等待,但现在有的正式组成部分---SwipeRefreshLayout ...

  9. XListView下拉刷新和上拉加载更多详解

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.博客链接地址:小杨的博客 http://blog.csdn.net/qq_32059827/article/details/53167655 市面上有 ...

随机推荐

  1. SQL 增删改查45道题

    create database School use School go create table Student --1.学生表 ( Sno ) not null primary key,--学号( ...

  2. dubbox注解的一个坑

    我和我同事Daniel排查的一个问题,原文是我同事Daniel写的,我做了些修改了补充. 我们dubbox的provider端有很多service开发时没有考虑到幂等问题,于是只能暂时关掉dubbo的 ...

  3. HDU 3782 xxx定律

    xxx定律 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  4. Android7.0 Phone应用源码分析(三) phone拒接流程分析

    本文主要分析Android拒接电话的流程,下面先来看一下拒接电话流程时序图 步骤1:滑动按钮到拒接图标,会调用到AnswerFragment的onDecline方法 com.android.incal ...

  5. Spring MVC 的环境搭建和入门小程序

    1.1.下载spring框架包. 1.1.1百度搜索Spring Framework. 进入spring官网,在网页右边选择想要下载的版本.如图 1.1.2进入页面按Ctrl+F搜索Distribut ...

  6. VS error 全集(error C2664: 'CWnd::MessageBoxW' : cannot convert parameter 1 from 'char *' to 'LPCTSTR'的解决方法)

    我用的是VS2005,在编译MFC时遇到了如下错误: error C2664: 'CWnd::MessageBoxW' : cannot convert parameter 1 from 'char ...

  7. 用Ajax实现自动刷新news功能

    这是Ajax应用的一个小实例:在页面中自动刷新功能,比如整个新闻页面中某一个小版块的内容,无需刷新整个页面就可以自动更新: 1.首先创建简单的页面元素: <body> <input ...

  8. nginx.conf完整配置实例

        #user nobody; worker_processes 1;   #error_log logs/error.log; #error_log logs/error.log notice; ...

  9. ConcurrentHashMap源码分析

    看过hashMap源码之后一直意犹未尽的感觉,挡不住我看其他的源码了.HashMap在单线程中非常好用,也不会出现什么问题,但是一到多线程就gg了,变的不灵了.我们有HashTable可以运用在多线程 ...

  10. vsftp之虚拟用户

    1.安装: yum install -y vsftpd yum install -y lftp2.创建用户useradd virftp -s /sbin/nologin3.创建虚拟用户及其存放路径vi ...