1.自定义view
public class SwipeLayout extends FrameLayout {
private ViewDragHelper dragHelper;
private View mFrontView;
private View mBackView;
private int mFrontWidth;
private int mBackWidth;
private int mFrontdHeight;
public static Status status = Status.Close;
private OnSwipeLayoutListener swipeLayoutListener;
// 枚举,三种状态
public static enum Status {
Close, Open, Draging
}
public void setSwipeLayoutListener(OnSwipeLayoutListener swipeLayoutListener) {
this.swipeLayoutListener = swipeLayoutListener;
}
public static interface OnSwipeLayoutListener {
void onClose(SwipeLayout mSwipeLayout);
void onOpen(SwipeLayout mSwipeLayout);
void onDraging(SwipeLayout mSwipeLayout);
// 要去关闭
void onStartClose(SwipeLayout mSwipeLayout);
// 要去开启
void onStartOpen(SwipeLayout mSwipeLayout);
}
public SwipeLayout(Context context) {
super(context);
init();
}
public SwipeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SwipeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
dragHelper = ViewDragHelper.create(this, 1.0f, mCallback);
}
ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View arg0, int arg1) {
// 1.返回值是否可以拖拽
return true;
}
@Override
public void onViewCaptured(View capturedChild, int activePointerId) {
// 2.被捕获时调用
super.onViewCaptured(capturedChild, activePointerId);
}
@Override
public int getViewHorizontalDragRange(View child) {
// 3.返回拖拽的范围, 不对拖拽进行真正的限制. 仅仅决定了动画执行速度,通过这个范围计算出速度
return mBackWidth;
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
// 4.就这么定义
// 根据建议值 修正将要移动到的(横向)位置 (重要)
// 此时没有发生真正的移动
// child: 当前拖拽的View
// left 新的位置的建议值, dx 位置变化量
// left = oldLeft + dx;
if (child == mFrontView) {
fixLeft(left);
}
return left;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top,
int dx, int dy) {
// 5.位置改变执行
super.onViewPositionChanged(changedView, left, top, dx, dy);
int newLeft = left;
// 滑动下页面,带动上边页滑动
if (changedView == mBackView) {
newLeft = mBackView.getLeft() + dx;
newLeft = fixBackLeft(newLeft);// 修正下页面
mBackView.layout(newLeft, 0, mBackWidth + newLeft,
mFrontdHeight);
mFrontView.layout(newLeft - mFrontWidth, 0, newLeft,
mFrontdHeight);
}
newLeft = fixLeft(newLeft);// 修正
// 滑动上边页,带动下页面滑动
if (changedView == mFrontView) {
mFrontView.layout(newLeft, 0, mFrontWidth + newLeft,
mFrontdHeight);
mBackView.layout(mFrontWidth + newLeft, 0, mFrontWidth
+ mBackWidth + newLeft, mFrontdHeight);
}
dispatchSwipeEvent();// 更新状态回调
invalidate();
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
// 6.松手时执行
super.onViewReleased(releasedChild, xvel, yvel);
if (xvel == 0 && mFrontView.getLeft() < -mBackWidth / 2.0f) {
open();
} else if (xvel < 0) {
open();
} else {
close();
}
}
};
protected void dispatchSwipeEvent() {
if (swipeLayoutListener != null) {
swipeLayoutListener.onDraging(this);
}
// 记录上一次的状态
Status preStatus = status;
// 更新当前状态
status = updateStatus();
if (preStatus != status && swipeLayoutListener != null) {
if (status == Status.Close) {
swipeLayoutListener.onClose(this);
} else if (status == Status.Open) {
swipeLayoutListener.onOpen(this);
} else if (status == Status.Draging) {
if (preStatus == Status.Close) {
swipeLayoutListener.onStartOpen(this);
} else if (preStatus == Status.Open) {
swipeLayoutListener.onStartClose(this);
}
}
}
}
//更新状态
private Status updateStatus() {
int left = mFrontView.getLeft();
if (left == 0) {
return Status.Close;
} else if (left == -mBackWidth) {
return Status.Open;
}
return Status.Draging;
}
// 刚开始时,设置好两个子view 的布局
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
mBackView.layout(mFrontWidth, 0, mFrontWidth + mBackWidth,
mFrontdHeight);
mFrontView.layout(0, 0, mFrontWidth, mFrontdHeight);
};
// 设置限制下页面位置
protected int fixBackLeft(int left) {
if (left < mFrontWidth - mBackWidth) {
return mFrontWidth - mBackWidth;
}
if (left > mFrontWidth) {
return mFrontWidth;
}
return left;
}
// 设置限制上页面位置
protected int fixLeft(int left) {
if (left > 0)
return 0;
if (left < -mBackWidth)
return -mBackWidth;
return left;
}
@Override
public void computeScroll() {
super.computeScroll();
// 持续平滑动画 (高频率调用)
if (dragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
public void open() {
int finalleft = -mBackWidth;
if (dragHelper.smoothSlideViewTo(mFrontView, finalleft, 0)) {// 左和上的位置
ViewCompat.postInvalidateOnAnimation(this);
}
}
public void close() {
int finalleft = 0;
if (dragHelper.smoothSlideViewTo(mFrontView, finalleft, 0)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
// 2.触摸事件传递
public boolean onInterceptTouchEvent(android.view.MotionEvent ev) {
return dragHelper.shouldInterceptTouchEvent(ev);
};
public boolean onTouchEvent(android.view.MotionEvent event) {
dragHelper.processTouchEvent(event);
return true;
};
// 3.得到子view
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mBackView = getChildAt(0);
mFrontView = getChildAt(1);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mFrontWidth = mFrontView.getMeasuredWidth();
mFrontdHeight = mFrontView.getMeasuredHeight();
mBackWidth = mBackView.getMeasuredWidth();
}
}
2.MainActivity,设置适配器
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyListView mList = (MyListView) findViewById(R.id.lv);
mList.setAdapter(new MyAdapter(MainActivity.this));
final View swipe = View.inflate(this, R.layout.item_list, null);
mList.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
SwipeLayout layout = (SwipeLayout) swipe;
layout.close();
}
});
}
}
3.适配器
public class MyAdapter extends BaseAdapter {
private Context context;
private ViewHolder holder;
private SwipeLayout swipeLayout;
private ArrayList<SwipeLayout> list;
public MyAdapter(Context context) {
this.context = context;
list = new ArrayList<SwipeLayout>();
}
@Override
public int getCount() {
return NAMES.length;
}
@Override
public Object getItem(int position) {
return NAMES[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
//holder = new ViewHolder();
view = View.inflate(context, R.layout.item_list, null);
//holder.tv_call = (TextView) view.findViewById(R.id.tv_call);
//holder.tv_del = (TextView) view.findViewById(R.id.tv_del);
//view.setTag(holder);
} else {
view = convertView;
//holder = (ViewHolder)view.getTag();
}
swipeLayout = (SwipeLayout) view;
//设置监听
swipeLayout.setSwipeLayoutListener(new OnSwipeLayoutListener() {
@Override
public void onStartOpen(SwipeLayout mSwipeLayout) {
//当又打开一个的时候,清除集合中所有数据
for (SwipeLayout swipeLayout : list) {
swipeLayout.close();
}
list.clear();
}
@Override
public void onStartClose(SwipeLayout mSwipeLayout) {
}
@Override
public void onOpen(SwipeLayout mSwipeLayout) {
list.add(mSwipeLayout);
}
@Override
public void onDraging(SwipeLayout mSwipeLayout) {
}
@Override
public void onClose(SwipeLayout mSwipeLayout) {
list.remove(mSwipeLayout);
}
});
return view;
}
static class ViewHolder {
TextView tv_call;
TextView tv_del;
}
}