Android实现下拉刷新上拉加载(PullToRefreshLayout)

各个组件位置:  导xutils包gson包配置网络权限

values包下面

strings修改

   

<?xml version="1.0" encoding="utf-8"?>
<resources>

<string name="app_name">Pull</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<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>

</resources>

 

添一个color.xml 在这可以修改颜色

   

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

 

在res文件夹下创个anim文件夹添加动画(两个)

/MainActivity/res/anim/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>

 

/MainActivity/res/anim/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>

 
   

在res下layout下添加两部局

/MainActivity/res/layout/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>

 
   

/MainActivity/res/layout/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>

 
   

修改/MainActivity/res/layout/activity_main.xml布局(注意红色包名)

<com.exaple.tong.PullToRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<include
layout="@layout/refresh_head"

/>
<com.exaple.tong.PullableListView
android:id="@+id/listview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world" />
<include
layout="@layout/load_more"

/>

</com.exaple.tong.PullToRefreshLayout>

 
   

/MainActivity/res/layout/base.xml  子布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >

<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hhh" />

</LinearLayout>

 
   

下面在src文件夹下

先创个com.exaple.tong包里面有三个类(固定的直接粘)

/MainActivity/src/com/exaple/tong/Pullable.java   (1)

package com.exaple.tong;

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

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

 
   

/MainActivity/src/com/exaple/tong/PullableListView.java    (2)

package com.exaple.tong;

 

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;
}
}

 
   

/MainActivity/src/com/exaple/tong/PullToRefreshLayout.java    (3)

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);

}

}

 
   

下面是MainActivity

/MainActivity/src/com/exmple/pull/MainActivity.java

package com.exmple.pull;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Window;

import com.chen.listTongyong.Base1;
import com.eample.vo.MyData;
import com.eample.vo.Super;
import com.exaple.tong.PullToRefreshLayout;
import com.exaple.tong.PullableListView;
import com.exaple.tong.PullToRefreshLayout.OnRefreshListener;
import com.google.gson.Gson;

public class MainActivity extends Activity {

Handler h = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
String result = (String) msg.obj;
Gson g = new Gson();
Super ms = g.fromJson(result, Super.class);
List<MyData> data = ms.getData();
list = data;
ba = new Base1(MainActivity.this, list);
plistview.setAdapter(ba);
}
if (msg.what == 2) {
String result = (String) msg.obj;
Gson g = new Gson();
Super ms = g.fromJson(result, Super.class);
List<MyData> data = ms.getData();
list.addAll(data);
ba.notifyDataSetChanged();
}

}

};

int page = 1;
String url = "http://api.expoon.com/AppNews/getNewsList/type/1/p/";
private List<MyData> list = new ArrayList<MyData>();
private Base1 ba;
private PullableListView plistview;
private PullToRefreshLayout layout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置隐藏标题
requestWindowFeature(Window.FEATURE_NO_TITLE);


setContentView(R.layout.activity_main);
//找控件
plistview = (PullableListView) findViewById(R.id.listview);
layout = (PullToRefreshLayout) findViewById(R.id.layout);
//刚进去显示数据
setJson(page);
layout.setOnRefreshListener(new OnRefreshListener() {
//下拉刷新
@Override
public void onRefresh(PullToRefreshLayout pullToRefreshLayout) {
h.postDelayed(new Runnable() {

@Override
public void run() {
int page = 1;
setJson(page);
layout.refreshFinish(PullToRefreshLayout.SUCCEED);

}
}, 10);

}
//加载更多
@Override
public void onLoadMore(PullToRefreshLayout pullToRefreshLayout) {
h.postDelayed(new Runnable() {

@Override
public void run() {

page++;
new Thread() {
public void run() {
String string = NetUtil.getData(url + page);

h.sendMessage(h.obtainMessage(2, string));
}
}.start();
layout.loadmoreFinish(PullToRefreshLayout.SUCCEED);

}
}, 10);

}
});

}

private void setJson(final int pa) {
new Thread() {
public void run() {
String string = NetUtil.getData(url + pa);

h.sendMessage(h.obtainMessage(1, string));
}
}.start();

}

}

 
   

/MainActivity/src/com/exmple/pull/NetUtil.java   请求数据

package com.exmple.pull;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.DefaultedHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

public class NetUtil {
public static String getData(String str){

String str1="";
HttpGet get=new HttpGet(str);
HttpParams parmas=new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(parmas, 5000);
HttpConnectionParams.setSoTimeout(parmas, 5000);
HttpClient client=new DefaultHttpClient(parmas);
try {
HttpResponse execute = client.execute(get);
if(execute.getStatusLine().getStatusCode()==200)
{
HttpEntity entity=execute.getEntity();
str1=EntityUtils.toString(entity, "UTF-8");
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str1;
}

}

 
   

下面是list集合的vo包(两个)

/MainActivity/src/com/eample/vo/Super.java   (1)

package com.eample.vo;

import java.util.List;

public class Super {
List<MyData> data;
String info;
int status;
public List<MyData> getData() {
return data;
}
public void setData(List<MyData> data) {
this.data = data;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
@Override
public String toString() {
return "Super [data=" + data + ", info=" + info + ", status=" + status
+ "]";
}
public Super(List<MyData> data, String info, int status) {
super();
this.data = data;
this.info = info;
this.status = status;
}
public Super() {
super();
// TODO Auto-generated constructor stub
}

}

 
   

/MainActivity/src/com/eample/vo/MyData.java  (2)

package com.eample.vo;

public class MyData {
String news_id;
String news_summary;
String news_title;
String pic_url;
public String getNews_id() {
return news_id;
}
public void setNews_id(String news_id) {
this.news_id = news_id;
}
public String getNews_summary() {
return news_summary;
}
public void setNews_summary(String news_summary) {
this.news_summary = news_summary;
}
public String getNews_title() {
return news_title;
}
public void setNews_title(String news_title) {
this.news_title = news_title;
}
public String getPic_url() {
return pic_url;
}
public void setPic_url(String pic_url) {
this.pic_url = pic_url;
}
@Override
public String toString() {
return "MyData [news_id=" + news_id + ", news_summary=" + news_summary
+ ", news_title=" + news_title + ", pic_url=" + pic_url + "]";
}
public MyData(String news_id, String news_summary, String news_title,
String pic_url) {
super();
this.news_id = news_id;
this.news_summary = news_summary;
this.news_title = news_title;
this.pic_url = pic_url;
}
public MyData() {
super();
// TODO Auto-generated constructor stub
}

}

 
   

下面是listview适配器

/MainActivity/src/com/chen/listTongyong/Base1.java

package com.chen.listTongyong;

import java.util.List;

import com.eample.vo.MyData;
import com.exaple.tong.PullToRefreshLayout;
import com.exaple.tong.PullToRefreshLayout.OnRefreshListener;
import com.exmple.pull.R;
import com.lidroid.xutils.BitmapUtils;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;


public class Base1 extends BaseAdapter {
Context co;
List<MyData> list;
private View view;
private ViewHolder vh;

public Base1(Context co, List<MyData> list) {
super();
this.co = co;
this.list = list;
}

@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
view = View.inflate(co, R.layout.base, null);
vh = new ViewHolder();
vh.image = (ImageView) view.findViewById(R.id.image);
vh.text = (TextView) view.findViewById(R.id.text);
view.setTag(vh);

} else {
view = convertView;
vh = (ViewHolder) view.getTag();

}

vh.text.setText(list.get(position).getNews_title());
BitmapUtils bit = new BitmapUtils(co);
bit.display(vh.image, list.get(position).getPic_url());

return view;
}

public class ViewHolder {
TextView text;
ImageView image;

}

 

}

 
   
posted @ 2016-04-12 19:30  只剩下我自己了  阅读(260)  评论(0)    收藏  举报