android 自定义弹性的ListView

来源:互联网 发布:淘宝货源供应商怎么找 编辑:程序博客网 时间:2024/05/22 14:36
public class MyListView extends ListView implements OnScrollListener {private Scroller mScroller;private OnScrollListener mScrollListener; // user's scroll listenerprivate float mLastY = -1; // save event yprivate int mTotalItemCount;// 实现回弹效果的调度器private ScheduledExecutorService schedulor;// 回弹时每次减少的高度private static final int PULL_BACK_REDUCE_STEP = 1;// 回弹时递减headview高度的频率, 注意以纳秒为单位private static final int PULL_BACK_TASK_PERIOD = 700;private View headerView;private boolean isBottom = false;private View footerView;private float deltaY;public MyListView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubinitWithContext(context);}public MyListView(Context context) {super(context);// TODO Auto-generated constructor stubinitWithContext(context);}public MyListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initWithContext(context);}// 实现回弹效果的handler,用于递减headview的高度并请求重绘private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (!isBottom) {AbsListView.LayoutParams params = (LayoutParams) headerView.getLayoutParams();// 递减高度params.height -= PULL_BACK_REDUCE_STEP;headerView.setLayoutParams(params);// 重绘headerView.invalidate();// 停止回弹时递减headView高度的任务if (params.height <= 0) {schedulor.shutdownNow();}} else {AbsListView.LayoutParams params = (LayoutParams) footerView.getLayoutParams();// 递减高度params.height -= PULL_BACK_REDUCE_STEP;footerView.setLayoutParams(params);// 重绘footerView.invalidate();// 停止回弹时递减headView高度的任务if (params.height <= 0) {isBottom = false;schedulor.shutdownNow();}}}};@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {// TODO Auto-generated method stubmTotalItemCount = totalItemCount;Log.e("onScroll", "firstVisibleItem=" + firstVisibleItem + "," + "visibleItemCount=" + visibleItemCount+ "totalItemCount=" + totalItemCount);if ((firstVisibleItem + visibleItemCount) == totalItemCount) {isBottom = true;}if (mScrollListener != null) {mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, mTotalItemCount);}}@Overridepublic void onScrollStateChanged(AbsListView arg0, int arg1) {// TODO Auto-generated method stub// 正在滚动时回调,回调2-3次,手指没抛则回调2次。scrollState = 2的这次不回调// 回调顺序如下// 第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滚动// 第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的动作(手指离开屏幕前,用力滑了一下)// 第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滚动// 当屏幕停止滚动时为0;当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1;// 由于用户的操作,屏幕产生惯性滑动时为2// 当滚到最后一行且停止滚动时,执行加载}@Overridepublic void setAdapter(ListAdapter adapter) {// TODO Auto-generated method stubaddFooterView(footerView);super.setAdapter(adapter);}private void initWithContext(Context context) {// TODO Auto-generated method stubmScroller = new Scroller(context, new DecelerateInterpolator());super.setOnScrollListener(this);headerView = new View(context);headerView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, 0));headerView.setBackgroundColor(Color.BLACK);addHeaderView(headerView);footerView = new View(context);footerView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, 0));}@Overridepublic boolean onTouchEvent(MotionEvent ev) {Log.e("MotionEventgetEdgeFlags()==",String.valueOf(ev.getEdgeFlags()));// TODO Auto-generated method stubif (mLastY == -1) {mLastY = ev.getRawY();Log.e("mLastY", String.valueOf(mLastY));}switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:// 初始触摸Log.e("MotionEvent.ACTION_DOWN","初始触摸" );mLastY = ev.getRawY();// 相对屏幕的位置if (schedulor != null) {schedulor.shutdown();}return super.onTouchEvent(ev);case MotionEvent.ACTION_MOVE:// 侧移if (schedulor != null) {schedulor.shutdown();}Log.e("MotionEvent.ACTION_MOVE","侧移" );Log.e("dsadas==", String.valueOf((mTotalItemCount-2))+"+"+String.valueOf(getLastVisiblePosition()));deltaY = ev.getRawY() - mLastY;int smoothY = (int) ((int) deltaY * 0.8);if ((getFirstVisiblePosition()==0)&&deltaY>0) {Log.e("Tag", String.valueOf(deltaY));headerView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, smoothY));headerView.invalidate();} else if ((getLastVisiblePosition()==mTotalItemCount-1)&&deltaY<0) {footerView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, Math.abs(smoothY)));footerView.invalidate();Log.e("onTouchEvent", String.valueOf(super.onTouchEvent(ev)));} return super.onTouchEvent(ev);case MotionEvent.ACTION_UP:// 以一定的频率递减headview的高度,实现平滑回弹Log.e("MotionEvent.ACTION_UP","抬手" );schedulor = Executors.newScheduledThreadPool(1);schedulor.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {handler.obtainMessage().sendToTarget();}}, 0, PULL_BACK_TASK_PERIOD, TimeUnit.NANOSECONDS);return super.onTouchEvent(ev);}// Log.e("super.onTouchEvent",String.valueOf( super.onTouchEvent(ev)));return false;}@Overridepublic void setOnScrollListener(OnScrollListener l) {mScrollListener = l;}

以上是实现弹性的ListView的主要代码,但是也遇到了问题,在上拉滑动然后快速下拉滑动的时候会报错,我认为是这界面的没来的及刷新,暂时未找到解决办法,需要大家指教一下,下面是代码的下载地址

http://download.csdn.net/detail/jinzhikai12/7692171

0 0