Android中View的移动以及View之间的碰撞

        View的移动和碰撞检测的核心就在于如何获取到View在屏幕中的位置,获取的方法很多,本文中直接使用View.getX() View.getY()方法获取到左上角的顶点位置,View之间的碰撞检测就是在View的移动过程中不断计算和特定View之间的距离。代码如下:

import android.content.Context;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

public class TouchMoveView extends RelativeLayout {
	private static final String TAG="TouchMoveView";
	private View mTargetView;
	private View mRedView, mBlueView, mGreenView, mYellowView;
	private RectF mRedRect,mBlueRect,mGreenRect,mYellowRect,mTargetRect;
	
	private View mParentView;
	public TouchMoveView(Context context) {
		this(context, null);
	}

	public TouchMoveView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		mTargetView = findViewById(R.id.target_view);
		mRedView = findViewById(R.id.red);
		mBlueView = findViewById(R.id.blue);
		mGreenView = findViewById(R.id.green);
		mYellowView = findViewById(R.id.yellow);
		
		mParentView=findViewById(R.id.parent_view);
	}
	
	private View mTouchedView;
	private float mInitX;
	private float mInitY;
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		initRect();
		float x=event.getX();
		float y=event.getY();
		int action=event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mTouchedView=getTouchedView((int)x, (int)y);
			if(null!=mTouchedView){
				mInitX=mTouchedView.getX();
				mInitY=mTouchedView.getY();
			}
			Log.e(TAG,"mTouchedView:"+mTouchedView);
			return true;
		case MotionEvent.ACTION_MOVE:
			if(null!=mTouchedView){
				float moveX=x-mTouchedView.getWidth()/2;
				float moveY=y-mTouchedView.getHeight()/2;
				Log.e(TAG,"moveX:"+moveX+"  moveY:"+moveY );
				mTouchedView.setX(moveX);
				mTouchedView.setY(moveY);
				
				if(isTwoViewClose(mTouchedView, mTargetView)){
					int colorRes=getColorRes(mTouchedView);
					mTargetView.setBackgroundColor(getResources().getColor(colorRes));
				}else{
					mTargetView.setBackgroundColor(getResources().getColor(R.color.black));
				}
			}
			return true;
		
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			if(null!=mTouchedView){
				mTouchedView.setX(mInitX);
				mTouchedView.setY(mInitY);
			}
			mTargetView.setBackgroundColor(getResources().getColor(R.color.black));
			return true;
		default:
			return false;
		}
	}
	private int getColorRes(View view){
		if(null==view){
			return R.color.black;
		}
		int id=view.getId();
		switch (id) {
		case R.id.blue:
			return R.color.blue;
		case R.id.red:
			return R.color.red;
		case R.id.green:
			return R.color.green;
		case R.id.yellow:
			return R.color.yellow;
		default:
			return R.color.black;
		}
	}
	
	private View getTouchedView(int x,int y){
		Log.e(TAG,"x:"+x+" y:"+y);
		Log.e(TAG,"mRedRect"+mRedRect);
		Log.e(TAG,"mBlueRect"+mBlueRect);
		Log.e(TAG,"mGreenRect"+mGreenRect);
		Log.e(TAG,"mYellowRect"+mYellowRect);
		if(mRedRect.contains(x, y)){
			return mRedView;
		}
		
		if(mBlueRect.contains(x, y)){
			return mBlueView;
		}
		
		if(mGreenRect.contains(x, y)){
			return mGreenView;
		}
		
		if(mYellowRect.contains(x, y)){
			return mYellowView;
		}
		return null;
		
	}
	private void initRect(){
		if(null==mRedRect){
			mRedRect=getRect(mRedView);
		}
		
		if(null==mBlueRect){
			mBlueRect=getRect(mBlueView);
		}
		if(null==mGreenRect){
			mGreenRect=getRect(mGreenView);
		}
		if(null==mYellowRect){
			mYellowRect=getRect(mYellowView);
		}
		if(null==mTargetRect){
			mTargetRect=getNormalRect(mTargetView);
		}
	}
	private RectF getNormalRect(View view){
		return new RectF(view.getX(),view.getY(),view.getX()+view.getWidth(),view.getY()+view.getHeight());
	}
	
	private RectF getRect(View view){
		RectF rectf=new RectF(view.getX(),view.getY()+mParentView.getY(),view.getX()+view.getWidth(),view.getY()+mParentView.getY()+view.getHeight());
		return rectf;
	}
	/**判断两个View是否相交
	 * @param src
	 * @param target
	 * @return
	 */
	private boolean isTwoViewClose(View src,View target){
		RectF rectSrc=getNormalRect(src);
		RectF rectTar=getNormalRect(target);
		return rectSrc.intersect(rectTar);
	}

项目地址:http://git.oschina.net/fengcunhan/TouchMove.git

你可能感兴趣的:(android,碰撞检测,View拖动)