一、简介:
  下拉刷新是一种特定的手动刷新交互,和其他的同类操作不同的地方在于它采用了更加直觉的下拉操作,所以它的交互足够清晰明显。
下拉刷新主要用在类似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. DevExpress控件之RepositoryItemComboBox

    RepositoryItemComboBox在嵌入到GridView后,如何获取当前所选的Item? 直接代码: ((RepositoryItemComboBox)gridView.Columns[& ...

  2. json-lib之复杂数据类型的转换

    在json字符串转java bean时,一般的对象,可以直接转,如:一个学生类,属性有姓名.年龄等 public class Student{ private String sname; privat ...

  3. 使用fullPage.js遇到的问题以及翻译

    使用fullPage.js做一简单页面,遇一古怪问题:.section中的h1标签始终被一插件生成的标签包裹,导致样式调整好不困难!花费数小时排查为何会生成这样一个标签,最终在fullPage.js的 ...

  4. vue.js学习第一节

    <div id="app" class="app"> <p>{{ message }}</p> <p>{{ in ...

  5. esri-leaflet入门教程(2)-地图的HelloWorld

    esri-leaflet入门教程(2)-地图的HelloWorld by 李远祥 常言道"君子性非异也,善假于物也".这句话在IT界同样也适用,只不过IT界有更为时髦的说法:&qu ...

  6. windows下搭建Nexus3私服和基于IDEA15的Maven学习笔记

    搭建Nexus私服. 首先去官网下载window下用的zip文件.https://www.sonatype.com/download-oss-sonatype. 解压之后包含下面两个文件 进入nexu ...

  7. 如何创建DLL文件

    动态链接库(DLL)是从C语言函数库和Pascal库单元的概念发展而来的.所有的C语言标准库函数都存放在某一函数库中.在链接应用程序的过程中,链接器从库文件中拷贝程序调用的函数代码,并把这些函数代码添 ...

  8. groovy hello world

    安装方法见官方文档http://groovy.codehaus.org/Installing+Groovy 用新一个文件HelloWorld.groovy,以utf8的编码保存,内容为: printl ...

  9. [转]支持向量机SVM总结

    首先,对于支持向量机(SVM)的简单总结: 1. Maximum Margin Classifier 2. Lagrange Duality 3. Support Vector 4. Kernel 5 ...

  10. 学习JVM--垃圾回收(二)GC收集器

    1. 前言 在上一篇文章中,介绍了JVM中垃圾回收的原理和算法.介绍了通过引用计数和对象可达性分析的算法来筛选出已经没有使用的对象,然后介绍了垃圾收集器中使用的三种收集算法:标记-清除.标记-整理.标 ...