Cómo determinar la colisión entre Vistas en la programación de Android
El núcleo de la detección de colisiones y movimientos de View es cómo obtener la posición de View en la pantalla. Hay muchas formas de obtenerla. En este artículo, View.getX() View.getY(). El método se utiliza directamente para obtener la posición superior izquierda. La posición del vértice de la esquina y la detección de colisiones entre Vistas son para calcular continuamente la distancia a una Vista específica durante el movimiento de la Vista.
El código es el siguiente:
importar android.content.Context;
importar android.graphics.RectF;
importar android.util.AttributeSet; p>
importar android.util.Log;
importar android.view.MotionEvent;
importar android.view.View;
importar android. widget.RelativeLayout ;
clase pública TouchMoveView extiende RelativeLayout {
cadena final estática privada TAG="TouchMoveView";
vista privada mTargetView;
Vista privada mRedView, mBlueView, mGreenView, mYellowView;
RectF privada mRedRect,mBlueRect,mGreenRect,mYellowRect,mTargetRect;
Vista privada mParentView;
pública TouchMoveView (contexto de contexto) {
this(context, null);
}
public TouchMoveView (contexto de contexto, AttributeSet attrs) {
super (contexto, atributos);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate( );
mTargetView = findViewById(R.id.target_view);
mRedView = findViewById(R.id.red);
mBlueView = findViewById(R .id.azul);
mGreenView = findViewById(R.id.green);
mYellowView = findViewById(R.id.amarillo);
mParentView =findViewById( R.id.parent_view);
}
Vista privada mTouchedView;
flotante privado mInitX;
flotante privado mInitY ;
p>@Override
public boolean onTouchEvent(evento MotionEvent) {
initRect();
float x=evento. obtenerX
();
float y=event.getY();
int action=event.getAction();
cambiar (acción) {
caso MotionEvent.ACTION_DOWN:
mTouchedView=getTouchedView((int)x, (int)y);
if(null!=mTouchedView){
mInitX=mTouchedView.getX();
mInitY=mTouchedView.getY();
}
Log.e(TAG,"mTouchedView: "+mTouchedView);
devuelve verdadero;
caso MotionEvent.ACTION_MOVE:
if(null!=mTouchedView){
flotante 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));
}
}
devuelve verdadero ;
caso MotionEvent.ACTION_UP:
caso MotionEvent.ACTION_CANCEL:
if(null!=mTouchedView){
mTouchedView.setX (mInitX);
mTouchedView.setY(
mInitY);
}
mTargetView.setBackgroundColor(getResources().getColor(R.color.black));
devuelve verdadero;
predeterminado:
devuelve falso;
}
}
private int getColorRes(Ver vista){
if(null==view){
return R.color.black;
}
int id=view.getId();
cambiar (id) {
caso R.id.blue:
devolver R.color.azul;
caso R.id .red:
devuelve R.color.red;
case R.id.green:
devuelve R.color.green;
caso R.id.amarillo:
devuelve R.color.amarillo;
predeterminado:
devuelve R.color.negro;
}
}
Vista privada 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)){
devolver mBlueView;
}
if(mGreenRect.contains(x, y)){
devolver mGreenView;
} p>
if(mYellowRect.contains(x, y)){
devolver mYellowView;
}
devolver nul
l;
}
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);
}
}
RectF privado getNormalRect(Ver vista){
devuelve nuevo RectF(view.getX(),view. getY(),view.getX()+view.getWidth(),view.getY()+view.getHeight());
}
RectF privado getRect(Ver vista ){
RectF rectf=nuevo RectF(view.getX(),view.getY()+mParentView.getY(),view.getX()+view.getWidth(),view.getY() +mParentView.getY()+view.getHeight());
return rectf;
}
/** Determinar si dos vistas se cruzan p >
* @param src
* @param target
* @return
*/
booleano privado isTwoViewClose( Ver src,Ver destino){
RectF rectSrc=getNormalRect(src);
RectF rectTar=getNormalRect(destino);
return rectSrc.intersect(rectTar ) ;
}