您好,登錄后才能下訂單哦!
ListView在實際實用中,一般都會有下新刷新和上拉加載的動態效果,今天要學的就是如何自定義帶下拉刷新的ListView。
原理解析:一般將有下拉刷新的listview分成四種不同的狀態來進行不同的顯示效果。
實現步驟:
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圖,于是就將這個狀態圖畫出來了。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。如果你想了解更多相關內容請查看下面相關鏈接
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。