Xlistview刷新

1、在自己的项目中按以往的方法写listview、grilview的布局、适配器、以及界面显示内容
2、在项目中引入第三方类库(这里以listview为例)
3、建议为该类库单独建立一个包。
4、导入如图所示的类到自己的项目中:
5、导入如图所示的类到自己的项目中,注:标号1必倒,
      标号2,当我们是listview时为pullableListView;
                  当我们是gridview时为pullablegridview,以此类推
6、导入drawable下的内容:
7、导入anim下的文件
8、导入values下的文件,注:需要将strings.xml下的除第一条外的文件复制到自己的string.xml文件中
        
9、导入layout下的最后两个文件
10、至此需要导入的类库完毕,打开报错的代码,进行改正(change、更改R包);
11、修改xml中的文件,如图
12、mainactivty的java代码中的修改
public class MainActivity extends Activity {

    int page = 1;
    private PullableListView lv;
    private Base ba;
    private List<Mydata> list = new ArrayList<Mydata>();
    private String url = "http://api.expoon.com/AppNews/getNewsList/type/1/p/";
    // 创建handler对象
    Handler h = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            String result = msg.obj.toString();
            Gson g = new Gson();
            MySupper ms = g.fromJson(result, MySupper.class);
            ArrayList<Mydata> data = ms.getData();
            if (page==1) {
                list.clear();
            }
            Log.e("111111111111", "11111111111111111111111111111");
            list.addAll(data);
            update();

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置隐藏标题
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 加载xml文件
        setContentView(R.layout.activity_main);
        PullToRefreshLayout layout = (PullToRefreshLayout) findViewById(R.id.layout);
        lv = (PullableListView) findViewById(R.id.list);
        setJson();
        layout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(final PullToRefreshLayout pullToRefreshLayout) {


                h.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        page = 1;
                        setJson();
                        // 千万别忘了告诉控件刷新完毕了哦!
                        pullToRefreshLayout
                                .refreshFinish(PullToRefreshLayout.SUCCEED);
                    }

                }, 1000);


            }

            @Override
            public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout) {

                h.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        page++;
                        setJson();
                        // 千万别忘了告诉控件加载完毕了哦!
                        pullToRefreshLayout
                                .loadmoreFinish(PullToRefreshLayout.SUCCEED);

                    }
                }, 1000);
            }
        });

    }

    public void setJson() {

        new Thread() {
            public void run() {
                try {
                    String string = MyHttpGet.getjson(url, page);
                    Message message = h.obtainMessage();
                    message.obj = string;
                    h.sendMessage(message);
                } catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }.start();

    }

    // 创建更新适配器的方法
    public void update() {
        // 判断ba是否为空
        if (ba == null) {
            ba = new Base(MainActivity.this, list);
            // 为lv添加适配器
            lv.setAdapter(ba);
        } else {
            // 刷新适配器
            ba.UpDataAdapter(list);
        }
    }

}
13、适配器要写刷新适配器的方法
//定义更新适配器的方法
    public void UpDataAdapter(List<Mydata> list){
        this.list=list;
        this.notifyDataSetChanged();
    }
14、如果页面是用fragment填充的viewpager,则在viewpager页面加载布局前写一个判断,以防止fragmen被销毁而导致的数据加载不出来:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // 填充布局
        if (v==null) {
            v = View.inflate(getActivity(), R.layout.tuijian, null);
            layout = (PullToRefreshLayout) v
            .findViewById(R.id.layout);

        }
        ViewGroup mParent = (ViewGroup) v.getParent();

        if(mParent!=null){
            mParent.removeView(v);
        }

        lv = (PullableListView) v.findViewById(R.id.listview);

 Pullable.java; 

,直接沾
package com.jingchen.pulltorefresh.pullableview;

public interface Pullable
{
	/**
	 * 判断是否可以下拉,如果不需要下拉功能可以直接return false
	 * 
	 * @return true如果可以下拉否则返回false
	 */
	boolean canPullDown();

	/**
	 * 判断是否可以上拉,如果不需要上拉功能可以直接return false
	 * 
	 * @return true如果可以上拉否则返回false
	 */
	boolean canPullUp();
}

  PullableListView.java 

,直接沾

package com.chen.listTongyong;

import com.exaple.tong.Pullable;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ListView;

public class PullableListView extends ListView implements Pullable
{

public PullableListView(Context context)
{
super(context);
}

public PullableListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}

public PullableListView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}

@Override
public boolean canPullDown()
{
if (getCount() == 0)
{
// 娌℃湁item鐨勬椂鍊欎篃鍙�互涓嬫媺鍒锋柿
return true;
} else if (getFirstVisiblePosition() == 0
&& getChildAt(0).getTop() >= 0)
{
// 婊戝埌ListView鐨勯《閮ㄤ簡
return true;
} else
return false;
}

@Override
public boolean canPullUp()
{
if (getCount() == 0)
{
// 娌℃湁item鐨勬椂鍊欎篃鍙�互涓婃媺鍔犺浿
return true;
} else if (getLastVisiblePosition() == (getCount() - 1))
{
// 婊戝埌搴曢儴浜�
if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
&& getChildAt(
getLastVisiblePosition()
- getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
return true;
}
return false;
}
}

  

PullToRefreshLayout.java ,直接沾

package com.exaple.tong;


import java.util.Timer;
import java.util.TimerTask;

import com.exmple.pull.R;


import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
* 閼奉亜鐣炬稊澶屾畱鐢�啫鐪�敍宀�暏閺夈儳顓搁悶鍡曠瑏娑擃亜鐡欓幒褌娆㈤敍灞藉従娑擃厺绔存稉顏呮Ц娑撳�濯烘径杈剧礉娑擄拷閲滈弰顖氬瘶閸氼偄鍞寸�鍦�畱pullableView閿涘牆褰叉禒銉︽Ц鐎圭偟骞嘝ullable閹恒儱褰涢惃鍕�畱娴犺�缍峍iew閿涘�绱�
* 鏉╂ɑ婀佹稉锟介嚋娑撳﹥濯烘径杈剧礉閺囨潙顦跨拠锕佇掔憴浣稿触鐎诡晭ttp://blog.csdn.net/zhongkejingwang/article/details/38868463
*
* @author 闂勫牓娼�
*/
public class PullToRefreshLayout extends RelativeLayout
{
public static final String TAG = "PullToRefreshLayout";
// 閸掓繂顫愰悩鑸碉拷
public static final int INIT = 0;
// 闁插﹥鏂侀崚閿嬫煀
public static final int RELEASE_TO_REFRESH = 1;
// 濮濓絽婀�崚閿嬫煀
public static final int REFRESHING = 2;
// 闁插﹥鏂侀崝鐘烘祰
public static final int RELEASE_TO_LOAD = 3;
// 濮濓絽婀�崝鐘烘祰
public static final int LOADING = 4;
// 閹垮秳缍旂�灞剧槸
public static final int DONE = 5;
// 瑜版挸澧犻悩鑸碉拷
private int state = INIT;
// 閸掗攱鏌婇崶鐐剁殶閹恒儱褰�
private OnRefreshListener mListener;
// 閸掗攱鏌婇幋鎰��
public static final int SUCCEED = 0;
// 閸掗攱鏌婃径杈�Е
public static final int FAIL = 1;
// 閹稿�绗匶閸ф劖鐖i敍灞肩瑐娑擄拷閲滄禍瀣╂�閻愮瓬閸ф劖鐖�
private float downY, lastY;

// 娑撳�濯洪惃鍕�獩缁傛眹锟藉▔銊﹀壈閿涙�ullDownY閸滃�ullUpY娑撳秴褰查懗钘夋倱閺冩湹绗夋稉锟�
public float pullDownY = 0;
// 娑撳﹥濯洪惃鍕�獩缁傦拷
private float pullUpY = 0;

// 闁插﹥鏂侀崚閿嬫煀閻ㄥ嫯绐涚粋锟�
private float refreshDist = 200;
// 闁插﹥鏂侀崝鐘烘祰閻ㄥ嫯绐涚粋锟�
private float loadmoreDist = 200;

private MyTimer timer;
// 閸ョ偞绮撮柅鐔峰�
public float MOVE_SPEED = 8;
// 缁楊兛绔村▎鈩冨⒔鐞涘苯绔风仦锟�
private boolean isLayout = false;
// 閸︺劌鍩涢弬鎷岀箖缁嬪�鑵戝�鎴濆З閹垮秳缍�
private boolean isTouch = false;
// 閹靛�瀵氬�鎴濆З鐠烘繄顬囨稉搴濈瑓閹峰�銇旈惃鍕�拨閸斻劏绐涚粋缁樼槷閿涘奔鑵戦梻缈犵窗闂呭繑顒滈崚鍥у毐閺佹澘褰夐崠锟�
private float radio = 2;

// 娑撳�濯虹粻顓炪仈閻ㄥ嫯娴�80鎺抽崝銊ф暰
private RotateAnimation rotateAnimation;
// 閸у洤瀵戦弮瀣�祮閸斻劎鏁�
private RotateAnimation refreshingAnimation;

// 娑撳�濯烘径锟�
private View refreshView;
// 娑撳�濯洪惃鍕�唲婢讹拷
private View pullView;
// 濮濓絽婀�崚閿嬫煀閻ㄥ嫬娴橀弽锟�
private View refreshingView;
// 閸掗攱鏌婄紒鎾寸亯閸ョ偓鐖�
private View refreshStateImageView;
// 閸掗攱鏌婄紒鎾寸亯閿涙碍鍨氶崝鐔稿灗婢惰精瑙�
private TextView refreshStateTextView;

// 娑撳﹥濯烘径锟�
private View loadmoreView;
// 娑撳﹥濯洪惃鍕�唲婢讹拷
private View pullUpView;
// 濮濓絽婀�崝鐘烘祰閻ㄥ嫬娴橀弽锟�
private View loadingView;
// 閸旂姾娴囩紒鎾寸亯閸ョ偓鐖�
private View loadStateImageView;
// 閸旂姾娴囩紒鎾寸亯閿涙碍鍨氶崝鐔稿灗婢惰精瑙�
private TextView loadStateTextView;

// 鐎圭偟骞囨禍鍝杣llable閹恒儱褰涢惃鍒卛ew
private View pullableView;
// 鏉╁洦鎶ゆ径姘卞仯鐟欙妇顫�
private int mEvents;
// 鏉╂瑤琚辨稉顏勫綁闁插繒鏁ら弶銉﹀付閸掔�ull閻ㄥ嫭鏌熼崥鎴�礉婵″倹鐏夋稉宥呭�閹貉冨煑閿涘苯缍嬮幆鍛�枌濠娐ゅ喕閸欘垯绗傞幏澶婂嫉閸欘垯绗呴幏澶嬫�濞屸剝纭舵稉瀣��
private boolean canPullDown = true;
private boolean canPullUp = true;

private Context mContext;

/**
* 閹笛嗩攽閼奉亜濮╅崶鐐寸泊閻ㄥ埅andler
*/
Handler updateHandler = new Handler()
{

@Override
public void handleMessage(Message msg)
{
// 閸ョ偛鑴婇柅鐔峰�闂呭繋绗呴幏澶庣獩缁傜北oveDeltaY婢х偛銇囬懓灞筋杻婢讹拷
MOVE_SPEED = (float) (8 + 5 * Math.tan(Math.PI / 2
/ getMeasuredHeight() * (pullDownY + Math.abs(pullUpY))));
if (!isTouch)
{
// 濮濓絽婀�崚閿嬫煀閿涘奔绗栧▽鈩冩箒瀵帮拷绗傞幒銊ф畱鐠囨繂鍨�幃顒�粻閿涘本妯夌粈锟藉�锝呮躬閸掗攱鏌�.."
if (state == REFRESHING && pullDownY <= refreshDist)
{
pullDownY = refreshDist;
timer.cancel();
} else if (state == LOADING && -pullUpY <= loadmoreDist)
{
pullUpY = -loadmoreDist;
timer.cancel();
}

}
if (pullDownY > 0)
pullDownY -= MOVE_SPEED;
else if (pullUpY < 0)
pullUpY += MOVE_SPEED;
if (pullDownY < 0)
{
// 瀹告彃鐣�幋鎰�礀瀵�拷
pullDownY = 0;
pullView.clearAnimation();
// 闂呮劘妫屾稉瀣��婢跺瓨妞傞張澶婂讲閼冲�绻曢崷銊ュ煕閺傚府绱濋崣顏呮箒瑜版挸澧犻悩鑸碉拷娑撳秵妲稿�锝呮躬閸掗攱鏌婇弮鑸靛�閺�懓褰夐悩鑸碉拷
if (state != REFRESHING && state != LOADING)
changeState(INIT);
timer.cancel();
requestLayout();
}
if (pullUpY > 0)
{
// 瀹告彃鐣�幋鎰�礀瀵�拷
pullUpY = 0;
pullUpView.clearAnimation();
// 闂呮劘妫屾稉濠冨�婢跺瓨妞傞張澶婂讲閼冲�绻曢崷銊ュ煕閺傚府绱濋崣顏呮箒瑜版挸澧犻悩鑸碉拷娑撳秵妲稿�锝呮躬閸掗攱鏌婇弮鑸靛�閺�懓褰夐悩鑸碉拷
if (state != REFRESHING && state != LOADING)
changeState(INIT);
timer.cancel();
requestLayout();
}
Log.d("handle", "handle");
// 閸掗攱鏌婄敮鍐ㄧ湰,娴兼俺鍤滈崝銊ㄧ殶閻⑩暙nLayout
requestLayout();
// 濞屸剝婀侀幏鏍ㄥ�閹存牞锟介崶鐐茶剨鐎瑰本鍨�
if (pullDownY + Math.abs(pullUpY) == 0)
timer.cancel();
}

};

public void setOnRefreshListener(OnRefreshListener listener)
{
mListener = listener;
}

public PullToRefreshLayout(Context context)
{
super(context);
initView(context);
}

public PullToRefreshLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
initView(context);
}

public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
initView(context);
}

private void initView(Context context)
{
mContext = context;
timer = new MyTimer(updateHandler);
rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
context, R.anim.reverse_anim);
refreshingAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
context, R.anim.rotating);
// 濞h�濮為崠锟斤拷鏉烆剙濮╅崝銊ф暰
LinearInterpolator lir = new LinearInterpolator();
rotateAnimation.setInterpolator(lir);
refreshingAnimation.setInterpolator(lir);
}

private void hide()
{
timer.schedule(5);
}

/**
* 鐎瑰本鍨氶崚閿嬫煀閹垮秳缍旈敍灞炬▔缁�搫鍩涢弬鎵�波閺嬫嚎锟藉▔銊﹀壈閿涙艾鍩涢弬鏉跨暚閹存劕鎮楁稉锟界暰鐟曚浇鐨熼悽銊ㄧ箹娑擃亝鏌熷▔锟�
*/
/**
* @param refreshResult
* PullToRefreshLayout.SUCCEED娴狅綀銆冮幋鎰��閿涘�ullToRefreshLayout.FAIL娴狅綀銆冩径杈�Е
*/
public void refreshFinish(int refreshResult)
{
refreshingView.clearAnimation();
refreshingView.setVisibility(View.GONE);
switch (refreshResult)
{
case SUCCEED:
// 閸掗攱鏌婇幋鎰��
refreshStateImageView.setVisibility(View.VISIBLE);
refreshStateTextView.setText(R.string.refresh_succeed);
refreshStateImageView
.setBackgroundResource(R.drawable.refresh_succeed);
break;
case FAIL:
default:
// 閸掗攱鏌婃径杈�Е
refreshStateImageView.setVisibility(View.VISIBLE);
refreshStateTextView.setText(R.string.refresh_fail);
refreshStateImageView
.setBackgroundResource(R.drawable.refresh_failed);
break;
}
if (pullDownY > 0)
{
// 閸掗攱鏌婄紒鎾寸亯閸嬫粎鏆�缁夛拷
new Handler()
{
@Override
public void handleMessage(Message msg)
{
changeState(DONE);
hide();
}
}.sendEmptyMessageDelayed(0, 1000);
} else
{
changeState(DONE);
hide();
}
}

/**
* 閸旂姾娴囩�灞剧槸閿涘本妯夌粈鍝勫�鏉炵晫绮ㄩ弸婧匡拷濞夈劍鍓伴敍姘��鏉炶棄鐣�幋鎰�倵娑擄拷鐣剧憰浣界殶閻€劏绻栨稉顏呮煙濞夛拷
*
* @param refreshResult
* PullToRefreshLayout.SUCCEED娴狅綀銆冮幋鎰��閿涘�ullToRefreshLayout.FAIL娴狅綀銆冩径杈�Е
*/
public void loadmoreFinish(int refreshResult)
{
loadingView.clearAnimation();
loadingView.setVisibility(View.GONE);
switch (refreshResult)
{
case SUCCEED:
// 閸旂姾娴囬幋鎰��
loadStateImageView.setVisibility(View.VISIBLE);
loadStateTextView.setText(R.string.load_succeed);
loadStateImageView.setBackgroundResource(R.drawable.load_succeed);
break;
case FAIL:
default:
// 閸旂姾娴囨径杈�Е
loadStateImageView.setVisibility(View.VISIBLE);
loadStateTextView.setText(R.string.load_fail);
loadStateImageView.setBackgroundResource(R.drawable.load_failed);
break;
}
if (pullUpY < 0)
{
// 閸掗攱鏌婄紒鎾寸亯閸嬫粎鏆�缁夛拷
new Handler()
{
@Override
public void handleMessage(Message msg)
{
changeState(DONE);
hide();
}
}.sendEmptyMessageDelayed(0, 1000);
} else
{
changeState(DONE);
hide();
}
}

private void changeState(int to)
{
state = to;
switch (state)
{
case INIT:
// 娑撳�濯虹敮鍐ㄧ湰閸掓繂顫愰悩鑸碉拷
refreshStateImageView.setVisibility(View.GONE);
refreshStateTextView.setText(R.string.pull_to_refresh);
pullView.clearAnimation();
pullView.setVisibility(View.VISIBLE);
// 娑撳﹥濯虹敮鍐ㄧ湰閸掓繂顫愰悩鑸碉拷
loadStateImageView.setVisibility(View.GONE);
loadStateTextView.setText(R.string.pullup_to_load);
pullUpView.clearAnimation();
pullUpView.setVisibility(View.VISIBLE);
break;
case RELEASE_TO_REFRESH:
// 闁插﹥鏂侀崚閿嬫煀閻樿埖锟�
refreshStateTextView.setText(R.string.release_to_refresh);
pullView.startAnimation(rotateAnimation);
break;
case REFRESHING:
// 濮濓絽婀�崚閿嬫煀閻樿埖锟�
pullView.clearAnimation();
refreshingView.setVisibility(View.VISIBLE);
pullView.setVisibility(View.INVISIBLE);
refreshingView.startAnimation(refreshingAnimation);
refreshStateTextView.setText(R.string.refreshing);
break;
case RELEASE_TO_LOAD:
// 闁插﹥鏂侀崝鐘烘祰閻樿埖锟�
loadStateTextView.setText(R.string.release_to_load);
pullUpView.startAnimation(rotateAnimation);
break;
case LOADING:
// 濮濓絽婀�崝鐘烘祰閻樿埖锟�
pullUpView.clearAnimation();
loadingView.setVisibility(View.VISIBLE);
pullUpView.setVisibility(View.INVISIBLE);
loadingView.startAnimation(refreshingAnimation);
loadStateTextView.setText(R.string.loading);
break;
case DONE:
// 閸掗攱鏌婇幋鏍у�鏉炶棄鐣�В鏇�礉閸熴儵鍏樻稉宥呬粵
break;
}
}

/**
* 娑撳秹妾洪崚鏈电瑐閹峰�鍨ㄦ稉瀣��
*/
private void releasePull()
{
canPullDown = true;
canPullUp = true;
}

/*
* 閿涘牓娼�Javadoc閿涘�鏁遍悥鑸靛付娴犺泛鍠呯�姘�Ц閸氾箑鍨庨崣鎴滅皑娴犺�绱濋梼鍙夘剾娴滃�娆㈤崘鑼�崐
*
* @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
switch (ev.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
downY = ev.getY();
lastY = downY;
timer.cancel();
mEvents = 0;
releasePull();
break;
case MotionEvent.ACTION_POINTER_DOWN:
case MotionEvent.ACTION_POINTER_UP:
// 鏉╁洦鎶ゆ径姘卞仯鐟欙妇顫�
mEvents = -1;
break;
case MotionEvent.ACTION_MOVE:
if (mEvents == 0)
{
if (pullDownY > 0
|| (((Pullable) pullableView).canPullDown()
&& canPullDown && state != LOADING))
{
// 閸欘垯浜掓稉瀣��閿涘本顒滈崷銊ュ�鏉炶姤妞傛稉宥堝厴娑撳�濯�
// 鐎电懓鐤勯梽鍛�拨閸斻劏绐涚粋璇蹭粵缂傗晛鐨�敍宀勶拷閹存劗鏁ら崝娑欏�閻ㄥ嫭鍔呯憴锟�
pullDownY = pullDownY + (ev.getY() - lastY) / radio;
if (pullDownY < 0)
{
pullDownY = 0;
canPullDown = false;
canPullUp = true;
}
if (pullDownY > getMeasuredHeight())
pullDownY = getMeasuredHeight();
if (state == REFRESHING)
{
// 濮濓絽婀�崚閿嬫煀閻ㄥ嫭妞傞崐娆捫曢幗鍝バ╅崝锟�
isTouch = true;
}
} else if (pullUpY < 0
|| (((Pullable) pullableView).canPullUp() && canPullUp && state != REFRESHING))
{
// 閸欘垯浜掓稉濠冨�閿涘本顒滈崷銊ュ煕閺傜増妞傛稉宥堝厴娑撳﹥濯�
pullUpY = pullUpY + (ev.getY() - lastY) / radio;
if (pullUpY > 0)
{
pullUpY = 0;
canPullDown = true;
canPullUp = false;
}
if (pullUpY < -getMeasuredHeight())
pullUpY = -getMeasuredHeight();
if (state == LOADING)
{
// 濮濓絽婀�崝鐘烘祰閻ㄥ嫭妞傞崐娆捫曢幗鍝バ╅崝锟�
isTouch = true;
}
} else
releasePull();
} else
mEvents = 0;
lastY = ev.getY();
// 閺嶈�宓佹稉瀣��鐠烘繄顬囬弨鐟板綁濮f柧绶�
radio = (float) (2 + 2 * Math.tan(Math.PI / 2 / getMeasuredHeight()
* (pullDownY + Math.abs(pullUpY))));
if (pullDownY > 0 || pullUpY < 0)
requestLayout();
if (pullDownY > 0)
{
if (pullDownY <= refreshDist
&& (state == RELEASE_TO_REFRESH || state == DONE))
{
// 婵″倹鐏夋稉瀣��鐠烘繄顬囧▽陇鎻�崚鏉垮煕閺傛壆娈戠捄婵堫瀲娑撴柨缍嬮崜宥囧Ц閹�焦妲搁柌濠冩杹閸掗攱鏌婇敍灞炬暭閸欐�濮搁幀浣疯礋娑撳�濯洪崚閿嬫煀
changeState(INIT);
}
if (pullDownY >= refreshDist && state == INIT)
{
// 婵″倹鐏夋稉瀣��鐠烘繄顬囨潏鎯у煂閸掗攱鏌婇惃鍕�獩缁傝�绗栬ぐ鎾冲�閻樿埖锟介弰顖氬灥婵��濮搁幀浣稿煕閺傚府绱濋弨鐟板綁閻樿埖锟芥稉娲�櫞閺�儳鍩涢弬锟�
changeState(RELEASE_TO_REFRESH);
}
} else if (pullUpY < 0)
{
// 娑撳�娼伴弰顖氬灲閺傤厺绗傞幏澶婂�鏉炵晫娈戦敍灞芥倱娑撳�绱濆▔銊﹀壈pullUpY閺勵垵绀嬮崐锟�
if (-pullUpY <= loadmoreDist
&& (state == RELEASE_TO_LOAD || state == DONE))
{
changeState(INIT);
}
// 娑撳﹥濯洪幙宥勭稊
if (-pullUpY >= loadmoreDist && state == INIT)
{
changeState(RELEASE_TO_LOAD);
}

}
// 閸ョ姳璐熼崚閿嬫煀閸滃苯濮炴潪鑺ユ惙娴f粈绗夐懗钘夋倱閺冩儼绻樼悰宀嬬礉閹碉拷浜抪ullDownY閸滃�ullUpY娑撳秳绱伴崥灞炬�娑撳秳璐�閿涘苯娲滃�銈堢箹闁插瞼鏁�pullDownY +
// Math.abs(pullUpY))鐏忓崬褰叉禒銉ょ瑝鐎电懓缍嬮崜宥囧Ц閹�椒缍旈崠鍝勫瀻娴滐拷
if ((pullDownY + Math.abs(pullUpY)) > 8)
{
// 闂冨弶顒涙稉瀣��鏉╁洨鈻兼稉顓☆嚖鐟欙箑褰傞梹鎸庡瘻娴滃�娆㈤崪宀�仯閸戣�绨ㄦ禒锟�
ev.setAction(MotionEvent.ACTION_CANCEL);
}
break;
case MotionEvent.ACTION_UP:
if (pullDownY > refreshDist || -pullUpY > loadmoreDist)
// 濮濓絽婀�崚閿嬫煀閺冭泛绶氭稉瀣��閿涘牊顒滈崷銊ュ�鏉炶姤妞傚�锟界瑐閹峰�绱氶敍宀勫櫞閺�儳鎮楁稉瀣��婢惰揪绱欐稉濠冨�婢惰揪绱氭稉宥夋�閽橈拷
{
isTouch = false;
}
if (state == RELEASE_TO_REFRESH)
{
changeState(REFRESHING);
// 閸掗攱鏌婇幙宥勭稊
if (mListener != null)
mListener.onRefresh(this);
} else if (state == RELEASE_TO_LOAD)
{
changeState(LOADING);
// 閸旂姾娴囬幙宥勭稊
if (mListener != null)
mListener.onLoadMore(this);
}
hide();
default:
break;
}
// 娴滃�娆㈤崚鍡楀絺娴溿倗绮伴悥鍓佽�
super.dispatchTouchEvent(ev);
return true;
}

/**
* @author chenjing 閼奉亜濮╁Ο鈩冨珯閹靛�瀵氬�鎴濆З閻ㄥ墖ask
*
*/
private class AutoRefreshAndLoadTask extends
AsyncTask<Integer, Float, String>
{

@Override
protected String doInBackground(Integer... params)
{
while (pullDownY < 4 / 3 * refreshDist)
{
pullDownY += MOVE_SPEED;
publishProgress(pullDownY);
try
{
Thread.sleep(params[0]);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
return null;
}

@Override
protected void onPostExecute(String result)
{
changeState(REFRESHING);
// 閸掗攱鏌婇幙宥勭稊
if (mListener != null)
mListener.onRefresh(PullToRefreshLayout.this);
hide();
}

@Override
protected void onProgressUpdate(Float... values)
{
if (pullDownY > refreshDist)
changeState(RELEASE_TO_REFRESH);
requestLayout();
}

}

/**
* 閼奉亜濮╅崚閿嬫煀
*/
public void autoRefresh()
{
AutoRefreshAndLoadTask task = new AutoRefreshAndLoadTask();
task.execute(20);
}

/**
* 閼奉亜濮╅崝鐘烘祰
*/
public void autoLoad()
{
pullUpY = -loadmoreDist;
requestLayout();
changeState(LOADING);
// 閸旂姾娴囬幙宥勭稊
if (mListener != null)
mListener.onLoadMore(this);
}

private void initView()
{
// 閸掓繂顫愰崠鏍︾瑓閹峰�绔风仦锟�
pullView = refreshView.findViewById(R.id.pull_icon);
refreshStateTextView = (TextView) refreshView
.findViewById(R.id.state_tv);
refreshingView = refreshView.findViewById(R.id.refreshing_icon);
refreshStateImageView = refreshView.findViewById(R.id.state_iv);
// 閸掓繂顫愰崠鏍︾瑐閹峰�绔风仦锟�
pullUpView = loadmoreView.findViewById(R.id.pullup_icon);
loadStateTextView = (TextView) loadmoreView
.findViewById(R.id.loadstate_tv);
loadingView = loadmoreView.findViewById(R.id.loading_icon);
loadStateImageView = loadmoreView.findViewById(R.id.loadstate_iv);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
Log.d("Test", "Test");
if (!isLayout)
{
// 鏉╂瑩鍣烽弰顖滎儑娑擄拷顐兼潻娑欐降閻ㄥ嫭妞傞崐娆忎粵娑擄拷绨洪崚婵嗩潗閸栵拷
refreshView = getChildAt(0);
pullableView = getChildAt(1);
loadmoreView = getChildAt(2);
isLayout = true;
initView();
refreshDist = ((ViewGroup) refreshView).getChildAt(0)
.getMeasuredHeight();
loadmoreDist = ((ViewGroup) loadmoreView).getChildAt(0)
.getMeasuredHeight();
}
// 閺�懓褰夌�鎰�付娴犲墎娈戠敮鍐ㄧ湰閿涘矁绻栭柌宀�纯閹恒儳鏁�pullDownY + pullUpY)娴f粈璐熼崑蹇曅╅柌蹇ョ礉鏉╂瑦鐗辩亸鍗炲讲娴犮儰绗夌�鐟扮秼閸撳秶濮搁幀浣风稊閸栧搫鍨�
refreshView.layout(0,
(int) (pullDownY + pullUpY) - refreshView.getMeasuredHeight(),
refreshView.getMeasuredWidth(), (int) (pullDownY + pullUpY));
pullableView.layout(0, (int) (pullDownY + pullUpY),
pullableView.getMeasuredWidth(), (int) (pullDownY + pullUpY)
+ pullableView.getMeasuredHeight());
loadmoreView.layout(0,
(int) (pullDownY + pullUpY) + pullableView.getMeasuredHeight(),
loadmoreView.getMeasuredWidth(),
(int) (pullDownY + pullUpY) + pullableView.getMeasuredHeight()
+ loadmoreView.getMeasuredHeight());
}

class MyTimer
{
private Handler handler;
private Timer timer;
private MyTask mTask;

public MyTimer(Handler handler)
{
this.handler = handler;
timer = new Timer();
}

public void schedule(long period)
{
if (mTask != null)
{
mTask.cancel();
mTask = null;
}
mTask = new MyTask(handler);
timer.schedule(mTask, 0, period);
}

public void cancel()
{
if (mTask != null)
{
mTask.cancel();
mTask = null;
}
}

class MyTask extends TimerTask
{
private Handler handler;

public MyTask(Handler handler)
{
this.handler = handler;
}

@Override
public void run()
{
handler.obtainMessage().sendToTarget();
}

}
}

/**
* 閸掗攱鏌婇崝鐘烘祰閸ョ偠鐨熼幒銉ュ經
*
* @author chenjing
*
*/
public interface OnRefreshListener
{
/**
* 閸掗攱鏌婇幙宥勭稊
*/
void onRefresh(PullToRefreshLayout pullToRefreshLayout);

/**
* 閸旂姾娴囬幙宥勭稊
*/
void onLoadMore(PullToRefreshLayout pullToRefreshLayout);


}

}

  anima下的两个文件

reverse_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="0"
    android:toDegrees="180" >

</rotate>

  rotating.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:fillAfter="true"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="-1"
    android:toDegrees="360" >

</rotate>

  load_more.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/loadmore_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:paddingBottom="20dp"
android:paddingTop="20dp" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >

<ImageView
android:id="@+id/pullup_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="60dp"
android:background="@drawable/pullup_icon_big" />

<ImageView
android:id="@+id/loading_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="60dp"
android:background="@drawable/loading"
android:visibility="gone" />

<TextView
android:id="@+id/loadstate_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/pullup_to_load"
android:textColor="@color/black"
android:textSize="16sp" />

<ImageView
android:id="@+id/loadstate_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/loadstate_tv"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>

</RelativeLayout>

  

  refresh_head.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/head_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/light_blue" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingBottom="20dp"
android:paddingTop="20dp" >

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >

<ImageView
android:id="@+id/pull_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="60dp"
android:background="@drawable/pull_icon_big" />

<ImageView
android:id="@+id/refreshing_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="60dp"
android:background="@drawable/refreshing"
android:visibility="gone" />

<TextView
android:id="@+id/state_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/pull_to_refresh"
android:textColor="@color/white"
android:textSize="16sp" />

<ImageView
android:id="@+id/state_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@id/state_tv"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>

</RelativeLayout>

  color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="white">#FFFFFF</color>
    <color name="black">#000000</color>
    <color name="gray">#aaaaaa</color>
    <color name="light_blue">#6593cb</color>
</resources>

 Values 下的

  
    <string name="head">这里是HeadView</string>
    <string name="pull_to_refresh">下拉刷新</string>
    <string name="release_to_refresh">释放立即刷新</string>
    <string name="refreshing">正在刷新...</string>
    <string name="refresh_succeed">刷新成功</string>
    <string name="refresh_fail">刷新失败</string>
    <string name="pullup_to_load">上拉加载更多</string>
    <string name="release_to_load">释放立即加载</string>
    <string name="loading">正在加载...</string>
    <string name="load_succeed">加载成功</string>
    <string name="load_fail">加载失败</string>

  

 

原文地址:https://www.cnblogs.com/jsonfan/p/5328336.html