自定义下拉刷新的listview
2016-03-26 21:36
399 查看
自定义下拉刷新的listview
listview的下拉刷新功能的实现依靠在listview前面加上头布局,通过判断头布局的位置确实用户是否下拉,然后根据情况进行处理1. 自定义一个类继承ListView
2. 自定义一个布局用于加入listView的头布局中
自定义的类代码如下:
public class ReflashListView extends ListView implements OnScrollListener { private final static int PULL_To_REFRESH = 0; // 下拉的状态值 private final static int REFRESHING = 1;// 正在刷新的状态值 private final static int RELEASE_REFRESH = 2; // 松开刷新的状态值 private LayoutInflater mInflater; private View mheardView; private ImageView ivArrow; private TextView tvTitle; private TextView tvTime; private ProgressBar pbProgress; private int mhearderHeight; // 下拉刷新布局的高度 private boolean isreflash; // 是否可以下拉刷新 private int startY = -1; private int state = PULL_To_REFRESH; // 记录当前状态 private Animation animUp; private Animation animDown; public ReflashListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initViews(); } public ReflashListView(Context context, AttributeSet attrs) { super(context, attrs); initViews(); } public ReflashListView(Context context) { super(context); initViews(); } private void initViews() { mInflater = LayoutInflater.from(getContext()); mheardView = mInflater.inflate(R.layout.list_reflash_heard_item, null); this.addHeaderView(mheardView); ivArrow = (ImageView) mheardView.findViewById(R.id.iv_arr); tvTitle = (TextView) mheardView.findViewById(R.id.tv_title); tvTime = (TextView) mheardView.findViewById(R.id.tv_date); pbProgress = (ProgressBar) mheardView.findViewById(R.id.pb_progress); measureView(mheardView); mhearderHeight = mheardView.getMeasuredHeight(); Log.d("tag", "mhearderHeight:" + mhearderHeight); topPadding(-mhearderHeight); addHeaderView(mheardView, null, false);// 将下拉布局加入listView顶部 setOnScrollListener(this); initArrowAnim(); } /** * 设置mheardView布局的上边距 * * @param i */ private void topPadding(int i) { mheardView.setPadding(mheardView.getPaddingLeft(), i, mheardView.getPaddingRight(), mheardView.getPaddingBottom()); mheardView.invalidate(); // 重新绘制mheardView } /** * 通知父布局headerView的尺寸(便于后面测量headerView的高度) * * @param child */ private void measureView(View child) { ViewGroup.LayoutParams params = child.getLayoutParams(); if (params == null) { params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } // 1.左右边距 2.内边距 3.子布局宽度 int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, params.width); int lpHeight = params.height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem == 0) { isreflash = true; } else { isreflash = false; } } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: startY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: if (startY == -1) {// 确保startY有效 startY = (int) ev.getRawY(); } if (state == REFRESHING) {// 正在刷新 break; } int tempY = (int) ev.getY(); int dy = tempY - startY; // 偏移量 Log.d("tag", "偏移量:" + dy); if (dy > 0) { int pading = dy - mhearderHeight; topPadding(pading); if (pading > 0 && state != RELEASE_REFRESH) { state = RELEASE_REFRESH; topPadding(0); refreshState(); } else if (pading < 0 && state != PULL_To_REFRESH) { state = PULL_To_REFRESH; refreshState(); } return true; } break; case MotionEvent.ACTION_UP: startY = -1;// 重置 if (state == RELEASE_REFRESH) { state = REFRESHING;// 正在刷新 topPadding(0); refreshState(); } else if (state == PULL_To_REFRESH) { topPadding(-mhearderHeight); } break; default: break; } return super.onTouchEvent(ev); } /** * 通过State值改变hearerView状态 */ private void refreshState() { switch (state) { case PULL_To_REFRESH: tvTitle.setText("下拉刷新"); ivArrow.setVisibility(View.VISIBLE); pbProgress.setVisibility(View.INVISIBLE); ivArrow.startAnimation(animDown); break; case RELEASE_REFRESH: tvTitle.setText("松开刷新"); ivArrow.setVisibility(View.VISIBLE); pbProgress.setVisibility(View.INVISIBLE); ivArrow.startAnimation(animUp); break; case REFRESHING: tvTitle.setText("正在刷新..."); ivArrow.clearAnimation();// 必须先清除动画,才能隐藏 ivArrow.setVisibility(View.INVISIBLE); pbProgress.setVisibility(View.VISIBLE); break; default: break; } } /** * 初始化箭头动画 */ private void initArrowAnim() { animUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animUp.setDuration(200); animUp.setFillAfter(true); animDown = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animDown.setDuration(200); animDown.setFillAfter(true); } }
相关文章推荐
- jar学习3
- 版本管理-gitlab
- Android项目通过NDK整合libjpg与libpng
- MySQL存储引擎--存储引擎的选择
- android 事件机制
- Jquery学习
- 包含在JAR文件中可直接访问的资源文件--ervlet 3.0新特性
- HDOJ 2070 Fibbonacci Number
- 感知哈希算法Java实现
- OC @property ,@synthesize和点语法的使用
- Ajax实现Web长连接
- Jbinding 大文件 解压缩7z文件 含password
- Activiti系列(一)——最简单的Activiti程序
- 旧系统升级改造那些二三事之策略
- 为什么java反射比较慢
- 代码健壮性 —— 异常保护和合法性检测
- Sql Server 编写分页存储过程
- 深入浅析JavaScript中的作用域和上下文
- 家具生产设计、家具数控、家居设计及销售设计
- Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解