Android自定義控件ListView下拉刷新的代碼

今天小編就爲大家分享一篇關於Android自定義控件ListView下拉刷新的代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

ListView在實際實用中,一般都會有下新刷新和上拉加載的動態效果,今天要學的就是如何自定義帶下拉刷新的ListView。

原理解析:一般將有下拉刷新的listview分成四種不同的狀態來進行不同的顯示效果。

  • 1.完成狀態done:listview正常顯示狀態
  • 2.下拉狀態pull:listview正在下拉時的狀態
  • 3.釋放狀態release:listview下拉後鬆開的狀態
  • 4.更新狀態refreshing:listview下拉後加載數據時的狀態

實現步驟:

  • 自定義CustomListView繼承自ListView,添加headerView,裏面的佈局是有下拉刷新的文字與圖片
  • 爲listview創建適配器,隨便弄一些數據做一些數據源放入到listview的適配器中,好測試顯示。
  • 自定義的帶有頭部的ListView首先要將頭部視圖隱藏掉,添加頭視圖的代碼是listview.addHeaderView()。
  • 注意:這裏並不能用headerView對象的setVisibility()來實現隱藏的效果,當你調用這個添加頭部視圖的方法時,頭部位置不管有沒有視圖都會佔據一個位置。所以得用setPadding()的TOP爲負數來實現這個功能。
  • 具體代碼實現
package com.hapzhu.customlv;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class CustomListview extends ListView {
  View headerView;
  int height;
  private TextView tvActionTip;
  private ImageView ivArrow;
  private ProgressBar pbRefreshing;
  final static int STATE_DONE = 1;
  final static int STATE_PULL = 2;
  final static int STATE_RELEASE = 3;
  final static int STATE_REFRESHING = 4;
  int currentState;
  int downY;
  public CustomListview(Context context, AttributeSet attrs) {
    super(context, attrs);
    headerView = View.inflate(context, R.layout.listview_header, null);
    this.addHeaderView(headerView);
    // 用setPadding方法設置Top的大小來把headerview隱藏掉
    // 不能用GetHeight方法來實現,因爲這個方法只能用來測試可見的控件
    // 要用measureHeight的方法來實現測試,這個方法要先測試0,0的位置
    headerView.measure(0, 0);
    height = headerView.getMeasuredHeight();
    headerView.setPadding(0, -height, 0, 0);
    initView();
    // 設置第一個狀態
    currentState = STATE_DONE;
  }
  private void initView() {
    tvActionTip = (TextView) headerView.findViewById(R.id.tv_state);
    ivArrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
    pbRefreshing = (ProgressBar) headerView.findViewById(R.id.progressBar);
  }
  boolean isRefresh = false;
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    try {
      // 事件類型
      int action = ev.getAction();
      switch (action) {
      case MotionEvent.ACTION_DOWN:// 往下滑的手勢
        if (currentState == STATE_DONE) {// 只有在完成狀態時纔會有業務動作
          // 觸發下拉手勢的Y座標
          downY = (int) ev.getY();
          // 切換狀態
          currentState = STATE_PULL;
        }
        break;
      case MotionEvent.ACTION_MOVE:// 正在拖動的手勢
        if (currentState == STATE_PULL) {// 只有在下拉狀態時纔會有動作
          int currentY = (int) ev.getY();// 得到正在不斷改變的當前Y座標
          int top = currentY - downY - height;// 這個值是下拉時頭部視圖的高度顯示,要慢慢變化
          headerView.setPadding(0, top, 0, 0);
          if (currentY - downY > height) {// 如果下拉的高度超過了頭視圖的高度,則改變狀態
            currentState = STATE_RELEASE;
            tvActionTip.setText("鬆開刷新");
          }
        }
        break;
      case MotionEvent.ACTION_UP:
        if (currentState == STATE_RELEASE) {// 只有在釋放狀態時才進行刷新動作
          tvActionTip.setText("刷新中");// 改變文字 提示
          currentState = STATE_REFRESHING;// 改變狀態,變爲刷新狀態
          ivArrow.setVisibility(GONE);// 箭頭隱藏
          pbRefreshing.setVisibility(VISIBLE);// 進度條顯示
          isRefresh = true;
          if(onRefreshListener!=null){
            //如果回調接口不爲空,則進行更新的事務
            onRefreshListener.OnRefresh(this);
          }
        } else {
          if (!isRefresh) {
            // 如果當前的下拉距離小於高度時,再把頭部視圖隱藏
            headerView.setPadding(0, -height, 0, 0);
            // 一定要記得把狀態改回去,不然會沒法再次向下拉
            currentState = STATE_DONE;
          }
        }
        break;
      }
    } catch (Exception e) {
    }
    return super.onTouchEvent(ev);
  }
  // 1定義接口
  interface OnRefreshListener {
    // 在主程序中使用框架中的Custom來改變數據更新完之後的界面
    public void OnRefresh(CustomListview customLv);
  }
  // 2.申明接口
  OnRefreshListener onRefreshListener;
  // 3.傳遞接口
  public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
    this.onRefreshListener = onRefreshListener;
  }
  public void refreshComplete(){
    isRefresh=false;
    //更新數據結果後,再回調這個方法
    headerView.setPadding(0, -height, 0, 0);
    // 一定要記得把狀態改回去,不然會沒法再次向下拉
    currentState = STATE_DONE;
    //將進度條設爲不可見,將箭頭設爲可見,將文字改回去
    ivArrow.setVisibility(VISIBLE);// 箭頭顯示
    pbRefreshing.setVisibility(GONE);// 進度條隱去
    tvActionTip.setText("下拉刷新");// 改變文字 提示
  }
}

今天新學了UML圖,於是就將這個狀態圖畫出來了。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對神馬文庫的支持。如果你想了解更多相關內容請查看下面相關鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章