重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
ListView在实际实用中,一般都会有下新刷新和上拉加载的动态效果,今天要学的就是如何自定义带下拉刷新的ListView。
成都创新互联主要业务有网站营销策划、成都网站设计、成都网站制作、外贸网站建设、微信公众号开发、微信小程序定制开发、H5场景定制、程序开发等业务。一次合作终身朋友,是我们奉行的宗旨;我们不仅仅把客户当客户,还把客户视为我们的合作伙伴,在开展业务的过程中,公司还积累了丰富的行业经验、网络营销推广资源和合作伙伴关系资源,并逐渐建立起规范的客户服务和保障体系。原理解析:一般将有下拉刷新的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("下拉刷新");// 改变文字 提示 } }