今天小編就爲大家分享一篇關於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圖,於是就將這個狀態圖畫出來了。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對神馬文庫的支持。如果你想了解更多相關內容請查看下面相關鏈接