android - traslacion - transformaciones en java 2d
¿Cómo establecer una matriz de transformación arbitraria a una vista? (3)
La respuesta de es genial, y la implementación de MyAnimation está aquí.
private class MyAnimation extends Animation {
private Matrix matrix;
public MyAnimation(Matrix matrix) {
this.matrix = matrix;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
t.getMatrix().set(matrix);
}
}
Desde Android 3.0, tenemos la posibilidad de establecer transformaciones 3D básicas en vistas usando setRotationX y setRotationY, por ejemplo.
En un caso específico, necesitaría lograr una transformación compleja que esté girando alrededor de un punto de pivote distante y luego escalando en un punto de pivote diferente. Esto no es posible simplemente usando setScaleX / Y y setRotationX / Y ya que comparten el mismo punto de pivote.
¿Existe alguna forma sencilla de proporcionar la matriz deseada a la vista para su visualización?
Por ahora, he encontrado dos posibles soluciones:
Configure una matriz de rotación y luego úsela para asignar un punto {0,0}; aplique el punto resultante a la traducción de la Vista y luego use setScaleX / Y de la Vista para establecer la escala
Hackea el onDraw de la Vista y aplica la transformación en el lienzo. Agregue la lógica para revertir los eventos táctiles del mapa, también.
Ambos no son realmente convenientes ya que estoy construyendo un AdapterView que muestra sus elementos con un efecto configurable; por ejemplo, puede ser posible cambiar el efecto para que los elementos se distribuyan en un círculo o como un "flujo de cobertura".
La solución de animación anterior funciona, pero da como resultado infinitas llamadas a applyTransformation
que deja un poco que desear desde el punto de vista de la eficiencia. Además, si matas la animación, la matriz aplicada no es permanente para la vista, por lo que estás obligado a dejar que se ejecute para siempre. Aquí hay un enfoque alternativo menos intrépido que resulta en una sola llamada a setMatrix
cada vez que se llama a invalidate()
en la vista:
En la vista de los padres constructor:
setStaticTransformationsEnabled(true);
Luego en el cuerpo:
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
// apply transform to child view - child triggers this call by call to `invalidate()`
t.getMatrix().set(someMatrix);
return true;
}
Simplemente llame a invalidate()
en el niño cada vez que desee actualizar su matriz.
Yo también estoy destrozando mi cerebro por esto. Este es el mejor que he encontrado (super hacky):
MyAnimation animation = new MyAnimation(matrix);
animation.setDuration(0);
animation.setFillAfter(true);
view.setAnimation(animation);