4.模仿QQ侧滑删除




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

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值