package com.hjw.removelistview;android
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;ide
/**
* 水平滑動自帶刪除當前列表項功能的ListView
*
* @author 何佳偉
*
*/
public class RemoveListView extends ListView {
/**
* 滑動類
*/
private Scroller scroller;
/**
* 滑動刪除的列表項
*/
private View item;
/**
* 手指滑動的狀態
*/
private boolean isScroller;post
/** 要刪除的列表項的索引 */
private int position;
/** 屏幕的寬度 */
private int screenWidth;
/** 當前的x,y座標 */
private int curX, curY;
/** 上一個點的x座標 */
private int perX = 0;動畫
/** 按下去的x座標 */
private int downX;this
private onRemoveListenter removeListener;spa
public RemoveListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}.net
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;
}rem
@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); } } }}