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);
}
}
}
}