自定義ListView實作下拉重繪流程以及思路
- 前言:全域變數以及引數說明 (以及在重繪之后的介面回呼說明)
- 1.下拉重繪狀態 STATE_PULL_REFRESH (0 )
- 2.釋放重繪狀態 STATE_RELEASE_REFRESH (1)
- 3.正在重繪 STATE_REFRESHING_REFRESH (2)
- 4.回呼介面(OnRefreshListener)
- 總結
前言:全域變數以及引數說明 (以及在重繪之后的介面回呼說明)
public class PullRefresh extends ListView {
private static final int STATE_PULL_REFRESH = 0; //下拉重繪狀態
private static final int STATE_RELEASE_REFRESH = 1; //松開重繪的狀態
private static final int STATE_REFRESHING_REFRESH = 2; //正在重繪
private OnRefreshListener onRefreshListener; //回呼介面
private int CurrentStateCode = STATE_PULL_REFRESH; //當前狀態
private View headView; //頭部布局檔案
private int measuredHeight, startY; //測量高度 && 初次點擊坐標
private RotateAnimation imageAnimaRotate, imageAnimaReset; // 旋轉影片 && 還原影片
介面回呼方法:
//介面回呼方法
public void onRefreshComplate(){
CurrentStateCode = STATE_PULL_REFRESH;
headView.setPadding(0,-measuredHeight,0,0); //重新設定內邊距
}
下拉重繪是否回呼判斷以及重繪狀態展示
public void refresh() {
switch (CurrentStateCode) {
case STATE_PULL_REFRESH:
pullPreImg.setVisibility(View.VISIBLE);
pullNextImg.setVisibility(View.GONE);
pullTv.setText("下拉重繪");
pullPreImg.startAnimation(imageAnimaReset);
break;
case STATE_RELEASE_REFRESH:
pullPreImg.setVisibility(View.VISIBLE);
pullNextImg.setVisibility(View.GONE);
pullTv.setText("釋放重繪");
pullPreImg.startAnimation(imageAnimaRotate);
break;
case STATE_REFRESHING_REFRESH:
pullPreImg.setVisibility(View.GONE);
pullNextImg.setVisibility(View.VISIBLE);
pullTv.setText("正在重繪");
pullPreImg.clearAnimation();
if(onRefreshListener != null){
onRefreshListener.refreshData(); //回呼
}
break;
}
}
1.下拉重繪狀態 STATE_PULL_REFRESH (0 )
-
手指點擊螢屏時觸發MotionEvent.ACTION_DOWN(按下)事件
- 在此事件中,獲取當前位置坐標,并且保存記錄
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
...
return true;
case MotionEvent.ACTION_UP:
...
break;
}
return super.onTouchEvent(ev);
}
2.釋放重繪狀態 STATE_RELEASE_REFRESH (1)
-
手指滑動下拉重繪的程序中,觸發MotionEvent.ACTION_MOVE(移動)事件,在此事件中需要做很多處理和判斷
- 1.判斷是否是 正在重繪 狀態 (如果是,下次滑動則不會生效)
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
...
case MotionEvent.ACTION_MOVE:
if (startY == -1) {
startY = (int) ev.getY();
}
if (CurrentStateCode == STATE_REFRESHING_REFRESH) {
break;
}
...
return true;
case MotionEvent.ACTION_UP:
...
break;
}
return super.onTouchEvent(ev);
}
2.判斷手指最后處于螢屏的距離與初次處于螢屏的距離只差是否為正數 并且當前狀態是否處于 釋放重繪 狀態 ( 設定狀態)
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
...
case MotionEvent.ACTION_MOVE:
...
int endY = (int) ev.getRawY();
int des = endY - startY;
if (des > 0 && CurrentStateCode != STATE_RELEASE_REFRESH)
{
CurrentStateCode = STATE_RELEASE_REFRESH;
headView.setPadding(0, des, 0, 0); //內邊距
refresh();
}
return true;
case MotionEvent.ACTION_UP:
...
break;
}
return super.onTouchEvent(ev);
}
3.判斷手指最后處于螢屏的距離與初次處于螢屏的距離只差是否為負數并且當前狀態是否處于 **下拉重繪** 狀態
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
...
case MotionEvent.ACTION_MOVE:
...
//接著判斷
else if (des < 0 && CurrentStateCode != STATE_PULL_REFRESH) {
CurrentStateCode = STATE_PULL_REFRESH;
refresh();
}
return true;
case MotionEvent.ACTION_UP:
...
break;
}
return super.onTouchEvent(ev);
}
4.設定事件攔截,消費事件,不交給系統處理,自己處理,(在滑動事件直接return true)
case MotionEvent.ACTION_MOVE:
...
return true;
3.正在重繪 STATE_REFRESHING_REFRESH (2)
-
手指在抬起的時候觸發 MotionEvent.ACTION_UP(抬起)事件
- 1.將初始化值設定為-1
- 2.判斷當前狀態是否為正在重繪狀態
- 3.如果當前狀態不是正在重繪 , 判斷當前狀態是否為下拉重繪狀態 , 重新設定內邊距
case MotionEvent.ACTION_UP:
startY = -1;
if (CurrentStateCode == STATE_RELEASE_REFRESH) {
CurrentStateCode = STATE_REFRESHING_REFRESH;
refresh();
} else if (CurrentStateCode == STATE_PULL_REFRESH) {
headView.setPadding(0, -measuredHeight, 0, 0);
refresh();
}
break;
4.回呼介面(OnRefreshListener)
public interface OnRefreshListener {
void refreshData();
}
在主函式中
...
mySelfListView.setOnRefreshListener(new OnRefreshListener() {
@Override
public void refreshData() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
... //更新資料操作
mySelfListView.onRefreshComplate(); //回呼方法
}
},2000); //模擬兩秒請求
}
});
...
總結
下拉重繪整個程序其實就是分為三步:點擊、滑動、松開,只要將三個狀態程序弄清楚,實作簡單的下拉重繪便變得沒那么復雜啦
原始碼已上傳GitHub(https://github.com/NoMessages/PullRefresh-Blog)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/226264.html
標籤:其他
上一篇:Android組件化開發簡單示例
下一篇:內嵌H5頁面的互動事件
