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

    一.基本类型​ byte: java中最小的数据类型.1字节/8位.-128(2^7)~127(2^7-1),默认值0. short: 短整型,2字节/16位,取值范围-32768(--2^15)~3 ...

  2. Linux驱动技术(七) _内核定时器与延迟工作

    内核定时器 软件上的定时器最终要依靠硬件时钟来实现,简单的说,内核会在时钟中断发生后检测各个注册到内核的定时器是否到期,如果到期,就回调相应的注册函数,将其作为中断底半部来执行.实际上,时钟中断处理程 ...

  3. iOS Storyboard创建APP 的国际化操作

    Storyboard创建APP 的国际化操作 最近在看<X-code江湖录>这本书,看到了APP 国际化这点,刚刚也简单的实践了一下.现在和大家分享分享! 写的这个简单的Demo全都是用 ...

  4. C语言 二维数组复制、清零及打印显示

    #include <stdlib.h> #include <stdio.h> #include <string.h> //二维整型数组打印显示 ],int row, ...

  5. Vuex 模块化与项目实例 (2.0)

    Vuex 强调使用单一状态树,即在一个项目里只有一个 store,这个 store 集中管理了项目中所有的数据以及对数据的操作行为.但是这样带来的问题是 store 可能会非常臃肿庞大不易维护,所以就 ...

  6. 使用批处理根据项目工程文件生成Nuget包并发布(支持.NET Core)

    最近在使用之前自己编写的批处理给.NET Core项目打包时出问题了,发现之前的脚本根本不适用了,折腾了半天,总算解决了.因此在这里分享下经验,并且奉上整理好的脚本. Nuget包这里就不多介绍了,需 ...

  7. warshall、

    #include<iostream> int mian() { ][],b[][],c[][]; int i,j,k; cout<<"input the Boolea ...

  8. groovy hello world

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

  9. gstunnel---一个网络安全管道

    项目简介: gstunnel 是 基于go 语言开发的一个安全网络管道,支持tcp协议. gstunnel分为client和server两部分. gstunnel 基于aes进行数据加密. 流程示意: ...

  10. Angular控制器

    这里使用的是angular-1.0.1.min.js Angular的前端渲染 <div> <ul> <li ng-repeat="i in [1,2,3]&q ...