2011-11-11 4 views
12

Tengo una vista personalizada donde uso transformaciones. Hasta ahora todo bien, funcionan como setRotationY(), setScaleX(), setTranslationY() o incluso getMatrix() funcionan como se esperaba, puedo manipular mi vista y se muestra bien. Donde golpeé la pared es que una serie de funciones se comportan de manera extraña después de eso. Por ejemplo, funciona como getHitRect() ¡devuelve valores totalmente extraños! Esto no está ayudando a mis eventos táctiles.Cómo obtener los límites adecuados de una vista después de la transformación Matrix

Intenté sobrecargar la función, pero aún está lejos de funcionar, especialmente cuando se usa la rotación o la escala (la traducción funciona bien). Creo que esto tiene algo que ver con el hecho de que la matriz se expresa en coordenadas para niños, entonces, ¿cómo puedo obtenerla en la coordinación de los padres?

@Override 
    public void getHitRect(Rect outRect){ 

     RectF rect = new RectF(); 
     rect.top = (float) this.getTop(); 
     rect.bottom = (float) this.getBottom(); 
     rect.left = (float) this.getLeft(); 
     rect.right = (float) this.getRight();  

    this.getMatrix().mapRect(rect); 
     rect.round(outRect); 
    } 

¿Se puede obtener un valor más directo directamente desde alguna función? Al igual que la nueva altura, ancho, arriba o abajo.

Respuesta

8

Al reemplazar el método “getChildStaticTransformation” de la ViewGroup o incluso con función de transformación como setRotationY(), setScaleX(), setTranslationY(), getMatrix() (disponible de API 11) sólo están afectando a la matriz de reproducción. Como resultado, su vista infantil personalizada devolverá Bounds "Rects" lejos de donde su hijo obtendrá el sorteo. Esto no es un problema la mayor parte del tiempo, pero cuando comienzas a estar dispuesto a hacer clic en él ... comienzan los problemas ... Aquí es cómo soluciono el problema. Estoy seguro de que podría haber mejores formas, pero como no he encontrado muchas cosas sobre el tema, aquí está.

En el ViewGroup sobrecarga:

public interface Itransformable { 
    public void setTransformationMatrix(Matrix trsMatrix); 
} 

@Override 
protected boolean getChildStaticTransformation(View child, Transformation t) { 
    if (child instanceof Itransformable){ 
     t.clear(); 
     t.setTransformationType(Transformation.TYPE_MATRIX); 
     ... 
     // Do whatever transformation you want here 
     ... 
     ((Itransformable)child).setTransformationMatrix(t.getMatrix()); 
     return true; 
    } else { 
     return false; 
    } 
} 

Aquí es el niño vista personalizada: Tenga en cuenta que no estoy almacenar directamente la matriz de transformación en la vista personalizada, pero en cambio el Rect transformado. Si desea almacenar la matriz (es decir, para una transformación posterior como punto ...) puede necesitar clonarla, ya que la matriz se alterará de alguna forma extraña, como si fuera un reciclaje o algo así.

public class MyCustomView extends View implements MyViewGroup.Itransformable{ 

private Rect mViewRect = null; 

public void setTransformationMatrix(Matrix trsMatrix){ 
    if (trsMatrix!=null){ 
     RectF rect = new RectF(); 
     rect.top = 0; 
     rect.bottom = (float) this.getHeight(); 
     rect.left = 0; 
     rect.right = (float) this.getWidth(); 

     trsMatrix.mapRect(rect); 
     rect.offset((float) this.getLeft(), (float) this.getTop()); 

     if (mViewRect == null) mViewRect = new Rect(); 
     rect.round(mViewRect); 
    } 
} 

public Rect getTransformatedRect() { 
    if (mViewRect!=null){ 
     // OutOfScreen WorkArround - As the view is not Displayed, mViewRect doesn't get updated. 
     if(getRight() < 0 || getLeft() > mParentWidth){ 
      return new Rect(getLeft(),getTop(),getRight(),getBottom()); 
     } else { 
      return mViewRect; 
     } 
    } else { 
     return new Rect(getLeft(),getTop(),getRight(),getBottom()); 
    } 
} 

@Override 
public void getHitRect(Rect outRect){ 

    if (mViewRect == null){ 
     super.getHitRect(outRect); 
    } else { 
     outRect.set(getTransformatedRect()); 
    } 
} 
+0

muchas gracias por su respuesta, me ayuda :) –

+0

Otra cosa para Android> = 4.0: 'getHitRect()' no se llamará automáticamente si se está haciendo clic en su punto de vista. Para agregar compatibilidad para proyectos que usan SDK <4.0, usar 'isTransformedTouchPointInView()' en el documento principal funciona incluso si no es perfecto. –

Cuestiones relacionadas