您好,登錄后才能下訂單哦!
ListView在實(shí)際實(shí)用中,一般都會(huì)有下新刷新和上拉加載的動(dòng)態(tài)效果,今天要學(xué)的就是如何自定義帶下拉刷新的ListView。
原理解析:一般將有下拉刷新的listview分成四種不同的狀態(tài)來進(jìn)行不同的顯示效果。
實(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)圖畫出來了。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)億速云的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
免責(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)容。