溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2020-10-15 06:21:19 來源:腳本之家 閱讀:174 作者:pigdreams 欄目:移動(dòng)開發(fā)

ListView在實(shí)際實(shí)用中,一般都會(huì)有下新刷新和上拉加載的動(dòng)態(tài)效果,今天要學(xué)的就是如何自定義帶下拉刷新的ListView。

原理解析:一般將有下拉刷新的listview分成四種不同的狀態(tài)來進(jìn)行不同的顯示效果。

  • 1.完成狀態(tài)done:listview正常顯示狀態(tài)
  • 2.下拉狀態(tài)pull:listview正在下拉時(shí)的狀態(tài)
  • 3.釋放狀態(tài)release:listview下拉后松開的狀態(tài)
  • 4.更新狀態(tài)refreshing:listview下拉后加載數(shù)據(jù)時(shí)的狀態(tài)

實(shí)現(xiàn)步驟:

  • 自定義CustomListView繼承自ListView,添加headerView,里面的布局是有下拉刷新的文字與圖片
  • 為listview創(chuàng)建適配器,隨便弄一些數(shù)據(jù)做一些數(shù)據(jù)源放入到listview的適配器中,好測(cè)試顯示。
  • 自定義的帶有頭部的ListView首先要將頭部視圖隱藏掉,添加頭視圖的代碼是listview.addHeaderView()。
  • 注意:這里并不能用headerView對(duì)象的setVisibility()來實(shí)現(xiàn)隱藏的效果,當(dāng)你調(diào)用這個(gè)添加頭部視圖的方法時(shí),頭部位置不管有沒有視圖都會(huì)占據(jù)一個(gè)位置。所以得用setPadding()的TOP為負(fù)數(shù)來實(shí)現(xiàn)這個(gè)功能。
  • 具體代碼實(shí)現(xiàn)
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方法設(shè)置Top的大小來把headerview隱藏掉
    // 不能用GetHeight方法來實(shí)現(xiàn),因?yàn)檫@個(gè)方法只能用來測(cè)試可見的控件
    // 要用measureHeight的方法來實(shí)現(xiàn)測(cè)試,這個(gè)方法要先測(cè)試0,0的位置
    headerView.measure(0, 0);
    height = headerView.getMeasuredHeight();
    headerView.setPadding(0, -height, 0, 0);
    initView();
    // 設(shè)置第一個(gè)狀態(tài)
    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:// 往下滑的手勢(shì)
        if (currentState == STATE_DONE) {// 只有在完成狀態(tài)時(shí)才會(huì)有業(yè)務(wù)動(dòng)作
          // 觸發(fā)下拉手勢(shì)的Y坐標(biāo)
          downY = (int) ev.getY();
          // 切換狀態(tài)
          currentState = STATE_PULL;
        }
        break;
      case MotionEvent.ACTION_MOVE:// 正在拖動(dòng)的手勢(shì)
        if (currentState == STATE_PULL) {// 只有在下拉狀態(tài)時(shí)才會(huì)有動(dòng)作
          int currentY = (int) ev.getY();// 得到正在不斷改變的當(dāng)前Y坐標(biāo)
          int top = currentY - downY - height;// 這個(gè)值是下拉時(shí)頭部視圖的高度顯示,要慢慢變化
          headerView.setPadding(0, top, 0, 0);
          if (currentY - downY > height) {// 如果下拉的高度超過了頭視圖的高度,則改變狀態(tài)
            currentState = STATE_RELEASE;
            tvActionTip.setText("松開刷新");
          }
        }
        break;
      case MotionEvent.ACTION_UP:
        if (currentState == STATE_RELEASE) {// 只有在釋放狀態(tài)時(shí)才進(jìn)行刷新動(dòng)作
          tvActionTip.setText("刷新中");// 改變文字 提示
          currentState = STATE_REFRESHING;// 改變狀態(tài),變?yōu)樗⑿聽顟B(tài)
          ivArrow.setVisibility(GONE);// 箭頭隱藏
          pbRefreshing.setVisibility(VISIBLE);// 進(jìn)度條顯示
          isRefresh = true;
          if(onRefreshListener!=null){
            //如果回調(diào)接口不為空,則進(jìn)行更新的事務(wù)
            onRefreshListener.OnRefresh(this);
          }
        } else {
          if (!isRefresh) {
            // 如果當(dāng)前的下拉距離小于高度時(shí),再把頭部視圖隱藏
            headerView.setPadding(0, -height, 0, 0);
            // 一定要記得把狀態(tài)改回去,不然會(huì)沒法再次向下拉
            currentState = STATE_DONE;
          }
        }
        break;
      }
    } catch (Exception e) {
    }
    return super.onTouchEvent(ev);
  }
  // 1定義接口
  interface OnRefreshListener {
    // 在主程序中使用框架中的Custom來改變數(shù)據(jù)更新完之后的界面
    public void OnRefresh(CustomListview customLv);
  }
  // 2.申明接口
  OnRefreshListener onRefreshListener;
  // 3.傳遞接口
  public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
    this.onRefreshListener = onRefreshListener;
  }
  public void refreshComplete(){
    isRefresh=false;
    //更新數(shù)據(jù)結(jié)果后,再回調(diào)這個(gè)方法
    headerView.setPadding(0, -height, 0, 0);
    // 一定要記得把狀態(tài)改回去,不然會(huì)沒法再次向下拉
    currentState = STATE_DONE;
    //將進(jìn)度條設(shè)為不可見,將箭頭設(shè)為可見,將文字改回去
    ivArrow.setVisibility(VISIBLE);// 箭頭顯示
    pbRefreshing.setVisibility(GONE);// 進(jìn)度條隱去
    tvActionTip.setText("下拉刷新");// 改變文字 提示
  }
}

今天新學(xué)了UML圖,于是就將這個(gè)狀態(tài)圖畫出來了。

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

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)億速云的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI