Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Cómo establecer una matriz de transformación arbitraria a una vista?

Desde Android 3.0, tenemos la posibilidad de establecer transformaciones 3D básicas en Views 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 escalado 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 manera sencilla de proporcionar la matriz deseada a la vista para mostrar?

Por ahora, he encontrado dos posibles soluciones:

  • Configure una matriz de rotación y luego utilícela para asignar un punto {0,0}; Aplique el punto resultante a la traducción de View y luego use setScaleX / Y de la vista para establecer la escala

  • Cortar el onDraw de la vista y aplicar la transformación en el lienzo. Añada la lógica para invertir eventos de mapa de contacto, también.

Ambos no son realmente convenientes ya que estoy construyendo un AdapterView que muestra sus elementos utilizando un efecto configurable; Por ejemplo, puede ser posible cambiar el efecto para tener los elementos ordenados en un círculo o como un "flujo de cubierta".

  • Android OpenCV getPerspectiveTransform y warpPerspective
  • ¿Cómo animar una matriz para "recortar" una imagen?
  • 3 Solutions collect form web for “Cómo establecer una matriz de transformación arbitraria a una vista?”

    Yo también estoy envolviendo mi cerebro con esto. Este es el mejor que he venido con (super hacky):

    MyAnimation animation = new MyAnimation(matrix); animation.setDuration(0); animation.setFillAfter(true); view.setAnimation(animation); 

    La solución de animación anterior funciona, pero resulta en llamadas infinitas 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 te obligas a dejarla correr para siempre. He aquí un enfoque alternativo menos hacky que da como resultado sólo una llamada a setMatrix cada vez que invalidate() en la vista se llama:

    En el constructor de vista de padres:

     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() al niño en cualquier momento que desee actualizar su matriz.

    La respuesta de xtravar es grande, 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); } } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.