水平滑动自带删除当前列表项功能的ListView

package com.hjw.removelistview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ListView;
import android.widget.Scroller;

/**
 * 水平滑动自带删除当前列表项功能的ListView
 *
 * @author 何佳伟
 *
 */
public class RemoveListView extends ListView {
 /**
  * 滑动类
  */
 private Scroller scroller;
 /**
  * 滑动删除的列表项
  */
 private View item;
 /**
  * 手指滑动的状态
  */
 private boolean isScroller;

 /** 要删除的列表项的索引 */
 private int position;
 /** 屏幕的宽度 */
 private int screenWidth;
 /** 当前的x,y坐标 */
 private int curX, curY;
 /** 上一个点的x坐标 */
 private int perX = 0;

 /** 按下去的x坐标 */
 private int downX;

 private onRemoveListenter removeListener;

 public RemoveListView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
 }

 public RemoveListView(Context context, AttributeSet attrs) {
  super(context, attrs);
  scroller = new Scroller(context, new AccelerateDecelerateInterpolator(
    context, attrs));
  screenWidth = getscreenWidth(context);
 }

 public RemoveListView(Context context) {
  super(context);
 }

 /**
  * 获得屏幕的宽度
  */
 private int getscreenWidth(Context context) {
  WindowManager w = (WindowManager) context
    .getSystemService(Context.WINDOW_SERVICE);
  DisplayMetrics metrics = new DisplayMetrics();
  w.getDefaultDisplay().getMetrics(metrics);
  return metrics.widthPixels;
 }

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  // 手指的x,y坐标
  curX = (int) ev.getX();
  curY = (int) ev.getY();

  // 如果滑动没有完成,就禁止其他Item滑动
  if (!scroller.isFinished()) {
   return false;
  }

  switch (ev.getAction()) {
  case MotionEvent.ACTION_DOWN:
   downX = curX;

   // 当前手指所在的列表项的索引
   int p = pointToPosition(curX, curY);
   // ListView中可见的第一个列表项的索引
   int n = getFirstVisiblePosition();
   // ListView中可见的View中手指所在的View
   item = getChildAt(p - n);
   position = p;
   break;

  case MotionEvent.ACTION_MOVE:
   isScroller = true;

   break;

  case MotionEvent.ACTION_UP:
   isScroller = false;

   break;
  }
  return super.dispatchTouchEvent(ev);
 }

 /**
  *
  */
 @Override
 public boolean onTouchEvent(MotionEvent ev) {
  int x = (int) ev.getX();// 手指所在的x坐标

  switch (ev.getAction()) {
  case MotionEvent.ACTION_DOWN:
   perX = x;

   break;

  case MotionEvent.ACTION_MOVE:
   if (isScroller) {
    // 水平实时滑动的距离
    int l = x - perX;
    Log.e("l", l + "");
    item.scrollBy(-l, 0);
   }
   perX = x;
   // Log.e("perX", perX + "");

   break;

  case MotionEvent.ACTION_UP:
   // 惯性滑动的距离
   int d = Math.abs(curX - downX);
   if (!isScroller) {
    // 滑动距离超过屏幕的1/3,滑动生效,继续惯性滑动。否则返回起始点
    if (d > screenWidth / 3) {
     // 向右惯性滑动
     if (curX > downX) {
      scroller.startScroll(-d, 0, -(screenWidth - d), 0, 1000);
     }
     // 向左惯性滑动
     else {
      scroller.startScroll(d, 0, screenWidth - d, 0, 1000);
     }
     postInvalidate();

    } else {
     item.scrollTo(0, 0);
    }
   }

   break;
  }
  return super.onTouchEvent(ev);
 }

 /**
  * 滑动删除的回调接口
  */
 public interface onRemoveListenter {
  /**
   * 删除动画完成时回调
   */
  public void onRemoveFinish(int position);
 }

 /**
  * 设置onRemoveListenter回调,实现数据更新
  */
 public void setOnRemoveListener(onRemoveListenter removeListener) {
  this.removeListener = removeListener;
 }

 @Override
 public void computeScroll() {
  super.computeScroll();
  // 滚动是否已经结束
  if (scroller.computeScrollOffset()) {
   item.scrollTo(scroller.getCurrX(), 0);
   postInvalidate();

   // 滑动完成,回到初始位置
   if (scroller.isFinished()) {
    item.scrollTo(0, 0);
    removeListener.onRemoveFinish(position);
   }
  }
 }
}

你可能感兴趣的:(水平滑动自带删除当前列表项功能的ListView)