标签:
一、布局
1.activity_main布局
<?xml version="1.0" encoding="UTF-8"?>
<pull_grid.PullToRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/refresh_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include layout="@layout/refresh_head" />
<pull_grid.PullableGridView
android:id="@+id/gv"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</pull_grid.PullableGridView>
<include layout="@layout/load_more" />
</pull_grid.PullToRefreshLayout>
2.refresh_head下拉布局
<?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/pullup_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>
3.load_more上拉布局
<?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>
4.menu-strat布局
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.liuweiqiang_2016.StratActivity" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/>
</menu>
5.color布局
<?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>
6.strings布局
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Liuweiqiang_2016</string>
<string name="hello_world">Hello world!</string>
<string name="action_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>
<string name="title_activity_strat">StratActivity</string>
</resources>
二、pull_grid包
7.Pullable类
package pull_grid;
public interface Pullable
{
/**
* 鍒ゆ柇鏄惁鍙互涓嬫媺锛屽鏋滀笉闇?瑕佷笅鎷夊姛鑳藉彲浠ョ洿鎺eturn false
*
* @return true濡傛灉鍙互涓嬫媺鍚﹀垯杩斿洖false
*/
boolean canPullDown();
/**
* 鍒ゆ柇鏄惁鍙互涓婃媺锛屽鏋滀笉闇?瑕佷笂鎷夊姛鑳藉彲浠ョ洿鎺eturn false
*
* @return true濡傛灉鍙互涓婃媺鍚﹀垯杩斿洖false
*/
boolean canPullUp();
}
8.PullableGridView类
package pull_grid;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;
public class PullableGridView extends GridView implements Pullable {
public PullableGridView(Context context) {
super(context);
}
public PullableGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PullableGridView(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) {
// 婊戝埌椤堕儴
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;
}
}
9.PullToRefreshLayout类
package pull_grid;
import java.util.Timer;
import java.util.TimerTask;
import com.example.liuweiqiang_2016.R;
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;
/**
* 閼奉亜鐣炬稊澶屾畱鐢啫鐪敍宀?鏁ら弶銉ь吀閻炲棔绗佹稉顏勭摍閹貉傛閿涘苯鍙炬稉顓濈娑擃亝妲告稉瀣婢惰揪绱濇稉锟芥稉顏呮Ц閸栧懎鎯堥崘鍛啇閻ㄥ埦ullableView閿涘牆褰叉禒銉︽Ц鐎圭偟骞嘝ullable閹恒儱褰涢惃鍕畱娴犺缍峍iew閿涘绱?
* 鏉╂ɑ婀佹稉锟芥稉顏冪瑐閹峰銇旈敍灞炬纯婢舵俺顕涚憴锝堫潌閸楁艾顓筯ttp://blog.csdn.net/zhongkejingwang/article/details/38868463
*/
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敍灞肩瑐娑擄拷娑擃亙绨ㄦ禒鍓佸仯Y閸ф劖鐖?
private float downY, lastY;
// 娑撳濯洪惃鍕獩缁傛眹锟藉倹鏁為幇蹇ョ窗pullDownY閸滃ullUpY娑撳秴褰查懗钘夋倱閺冩湹绗夋稉锟?0
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;
// 娑撳濯虹粻顓炪仈閻ㄥ嫯娴?180鎺抽崝銊ф暰
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);// 閹笛嗩攽閼奉亜濮╅崶鐐寸泊閻ㄥ埅andler
rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
context, R.anim.reverse_anim);// 娑撳濯虹粻顓炪仈閻ㄥ嫯娴?180鎺抽崝銊ф暰
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) {
// 閸掗攱鏌婄紒鎾寸亯閸嬫粎鏆?1缁夛拷
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) {
// 閸掗攱鏌婄紒鎾寸亯閸嬫粎鏆?1缁夛拷
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娑撳秳绱伴崥灞炬娑撳秳璐?0閿涘苯娲滃銈堢箹闁插瞼鏁?(pullDownY +
// Math.abs(pullUpY))鐏忓崬褰叉禒銉ょ瑝鐎电懓缍嬮崜宥囧Ц閹椒缍旈崠鍝勫瀻娴滐拷
if ((pullDownY + Math.abs(pullUpY)) > 8) {
// 闂冨弶顒涙稉瀣鏉╁洨鈻兼稉顓☆嚖鐟欙箑褰傞梹鎸庡瘻娴滃娆㈤崪宀?鍋i崙璁崇皑娴狅拷
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;
}
/**
* 閼奉亜濮╁Ο鈩冨珯閹靛瀵氬鎴濆З閻ㄥ墖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();
}
}
}
/**
* 閸掗攱鏌婇崝鐘烘祰閸ョ偠鐨熼幒銉ュ經
*
*/
public interface OnRefreshListener {
/**
* 閸掗攱鏌婇幙宥勭稊
*/
void onRefresh(PullToRefreshLayout pullToRefreshLayout);
/**
* 閸旂姾娴囬幙宥勭稊
*/
void onLoadMore(PullToRefreshLayout pullToRefreshLayout);
}
}
三、主类包
10.MainActivity类
package com.example.liuweiqiang_2016;
import java.util.List;
import java.util.concurrent.ExecutionException;
import com.example.liuweiqiang_2016.adapter.Gv_Base;
import com.example.liuweiqiang_2016.bean.All;
import com.example.liuweiqiang_2016.bean.Cont;
import com.google.gson.Gson;
import pull_grid.PullToRefreshLayout;
import pull_grid.PullToRefreshLayout.OnRefreshListener;
import pull_grid.PullableGridView;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnRefreshListener {
private PullToRefreshLayout refresh_view;
private String id;
private String uri = "http://apis.juhe.cn/goodbook/catalog?key=9d6ef8c31647a206e05fcaff70527182&dtype=json";
// private String path =
// "http://apis.juhe.cn/goodbook/query?key=9d6ef8c31647a206e05fcaff70527182&catalog_id="
// + id + "&rn=10&rn=10";
// private Handler mHandler = new Handler();
private boolean isExit = false;// 鍙屽嚮閫€鍑?
private PullableGridView gridview;
// 双击退出
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
isExit = false;// 鍙栨秷閫€鍑? }
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
refresh_view = (PullToRefreshLayout) findViewById(R.id.refresh_view);
gridview = (PullableGridView) findViewById(R.id.gv);
refresh_view.setOnRefreshListener(this);
data();
}
private void data() {
//实例化对象
MyAsyncTask task = new MyAsyncTask();
try {
String str = task.execute(uri).get();
//gson解析
Gson g = new Gson();
All all = g.fromJson(str, All.class);
List<Cont> result = all.getResult();
for (int i = 0; i < result.size(); i++) {
id = result.get(i).getId();
}
//自定义适配器
Gv_Base base = new Gv_Base(MainActivity.this, result);
gridview.setAdapter(base);
base.notifyDataSetInvalidated();
//item项监听===跳转
gridview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent intent = new Intent(MainActivity.this,
StratActivity.class);
intent.putExtra("id", id);
startActivity(intent);
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 鍒锋柊
@Override
public void onRefresh(final PullToRefreshLayout pullToRefreshLayout) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
data();
pullToRefreshLayout.refreshFinish(PullToRefreshLayout.SUCCEED);
}
}, 1000);
}
// 鍔犺浇
@Override
public void onLoadMore(final PullToRefreshLayout pullToRefreshLayout) {
// TODO Auto-generated method stub
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
data();
pullToRefreshLayout.loadmoreFinish(PullToRefreshLayout.SUCCEED);
}
}, 1000);
}
public void exit() {
if (!isExit) {
isExit = true;// 鍑嗗閫€鍑?
Toast.makeText(getApplicationContext(), "双击退出", Toast.LENGTH_SHORT)
.show();
Message msg = Message.obtain();
mHandler.sendEmptyMessageDelayed(0, 2000);// 濡傛灉2绉掗挓鍐呮病鏈夋寜涓嬭繑鍥為敭锛屽垯鍚姩瀹氭椂鍣ㄥ彇娑堟帀鍒氭墠鎵ц鐨勪换鍔?
// } else {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
System.exit(0);
}
}
}
11.MyAsyncTask类
package com.example.liuweiqiang_2016;
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.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.os.AsyncTask;
import android.util.Log;
public class MyAsyncTask extends AsyncTask<String, Integer, String> {
private String string;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
// 瀹炰緥鍖栧璞?
HttpClient httpClient = new DefaultHttpClient();
// 璋冪敤post璇锋眰
HttpPost httpPost = new HttpPost(params[0]);
try {
HttpResponse execute = httpClient.execute(httpPost);
if (execute.getStatusLine().getStatusCode() == 200) {
// 鑾峰彇鏈嶅姟鍣ㄨ繑鍥炴暟鎹?
HttpEntity entity = execute.getEntity();
string = EntityUtils.toString(entity, "gbk");
Log.i("bbb", string);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return string;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
12.adapter适配器类
package com.example.liuweiqiang_2016.adapter;
import java.util.List;
import com.example.liuweiqiang_2016.R;
import com.example.liuweiqiang_2016.bean.Cont;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class Gv_Base extends BaseAdapter {
Context context;
List<Cont> result;
public Gv_Base(Context context, List<Cont> result) {
this.context = context;
this.result = result;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return result.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return result.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(context, R.layout.base, null);
holder.image = (ImageView) convertView
.findViewById(R.id.imageView1);
holder.tView1 = (TextView) convertView.findViewById(R.id.textView1);
holder.tView2 = (TextView) convertView.findViewById(R.id.textView2);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tView1.setText(result.get(position).getId());
holder.tView2.setText(result.get(position).getCatalog());
return convertView;
}
class ViewHolder {
ImageView image;
TextView tView1, tView2;
}
}
标签:
原文地址:http://blog.csdn.net/jsx9057/article/details/51468800