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图,于是就将这个状态图画出来了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对移动技术网的支持。如果你想了解更多相关内容请查看下面相关链接
如对本文有疑问, 点击进行留言回复!!
Android SDK Manager 不知为什么突然打不开了?看这里
监听Android系统发出的插入SD卡并且已正确安装(识别)时发出的广播
RecyclerView三种常用效果的实现方法-android-kotlin
Android Studio app启动错误 Error running :Default Activity not found
网友评论