Cómo rotar vistas sobre el cambio de orientación sin volver a crear el diseño?

Esta pregunta se ha hecho antes aquí, pero su respuesta es incorrecta. Me gustaría girar algunas vistas en el cambio de orientación de pantalla, pero quiero mantener el diseño sin cambios. Deberán girar 90, 180, 270 o 360 grados de acuerdo con la orientación actual ( SCREEN_ORIENTATION_LANDSCAPE , SCREEN_ORIENTATION_PORTRAIT , SCREEN_ORIENTATION_REVERSE_LANDSCAPE , SCREEN_ORIENTATION_REVERSE_PORTRAIT ).

Esto es lo que quiero lograr:

Ejemplo de diseño

La respuesta en el enlace que mencioné declaró que debería crear un nuevo diseño diferente en el layout-land . Claramente, esto no es lo que quiero. No quiero recrear la actividad ni cambiar la orientación del diseño. Sólo quiero girar algunas vistas, y mantener otras opiniones sin cambios en el cambio de orientación.

Hay una enorme diferencia entre la rotación de vistas específicas y el cambio o la recreación de todo el diseño (tanto en el cambio de orientación).

Utilizando la respuesta en este enlace , podré obtener la orientación de pantalla actual con este método:

 public static int getScreenOrientation(Context context) { WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); int rotation = windowManager.getDefaultDisplay().getRotation(); DisplayMetrics dm = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; int orientation; // if the device's natural orientation is portrait: if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && height > width || (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && width > height) { switch (rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; case Surface.ROTATION_270: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; default: Log.e("ScreenOrientation", "Unknown screen orientation. Defaulting to " + "portrait."); orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; } } // if the device's natural orientation is landscape or if the device // is square: else { switch (rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; case Surface.ROTATION_270: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; default: Log.e("ScreenOrientation", "Unknown screen orientation. Defaulting to " + "landscape."); orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; } } return orientation; } 

Sobre el cambio de orientación, me gustaría hacer algo simple como esto:

 RotateAnimation rotateAnimation = new RotateAnimation(0, getScreenOrientation(getContext())); rotateAnimation.setDuration(2000); for (int i = 0; i < 63; i++) { Button button = (Button) rootView.findViewById(i); button.startAnimation(rotateAnimation); } 

Otra manera de reformular mi pregunta sería "¿Hay alguna manera de detectar el cambio de orientación en el método onConfigurationChanged() sin cambiar el diseño?". El problema es que no será capaz de detectar ningún cambio de orientación si ya deshabilito el cambio de orientación de diseño.

¿Alguien sabe cómo se hace? Yo podría haber pasado por los pasos equivocados, y creo que tendré que usar Acelerómetro Sensor o algo similar a eso para lograr lo que quiero, así que por favor guíame a través.

Intente utilizar OrientationEventListener . No es necesario usar onConfigurationChanged y android:configChanges="orientation|keyboardHidden|screenSize" .

Necesitas set android:screenOrientation="portrait" para la actividad en AndroidManifest.xml. Aquí está mi solución con OrientationEventListener :

 public class MyActivity extends Activity{ private ImageButton menuButton; private Animation toLandAnim, toPortAnim; private OrientationListener orientationListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout_image_ruler); menuButton=(ImageButton)findViewById(R.id.menu_button); toLandAnim= AnimationUtils.loadAnimation(this, R.anim.menubutton_to_landscape); toPortAnim= AnimationUtils.loadAnimation(this, R.anim.menubutton_to_portrait); orientationListener = new OrientationListener(this); } @Override protected void onStart() { orientationListener.enable(); super.onStart(); } @Override protected void onStop() { orientationListener.disable(); super.onStop(); } private class OrientationListener extends OrientationEventListener{ final int ROTATION_O = 1; final int ROTATION_90 = 2; final int ROTATION_180 = 3; final int ROTATION_270 = 4; private int rotation = 0; public OrientationListener(Context context) { super(context); } @Override public void onOrientationChanged(int orientation) { if( (orientation < 35 || orientation > 325) && rotation!= ROTATION_O){ // PORTRAIT rotation = ROTATION_O; menuButton.startAnimation(toPortAnim); } else if( orientation > 145 && orientation < 215 && rotation!=ROTATION_180){ // REVERSE PORTRAIT rotation = ROTATION_180; menuButton.startAnimation(toPortAnim); } else if(orientation > 55 && orientation < 125 && rotation!=ROTATION_270){ // REVERSE LANDSCAPE rotation = ROTATION_270; menuButton.startAnimation(toLandAnim); } else if(orientation > 235 && orientation < 305 && rotation!=ROTATION_90){ //LANDSCAPE rotation = ROTATION_90; menuButton.startAnimation(toLandAnim); } } } } 

Esto también previene de rotaciones demasiado frecuentes cuando la orientation es de 45, 135 … etc. Espero que ayude.

Los fundamentos son en realidad mucho más fácil. Echa un vistazo a Handling Runtime Changes .

Primero lo primero, al establecer

 android:configChanges="orientation|keyboardHidden|screenSize" 

En su Manifiesto en su etiqueta de actividad puede manejar el cambio de orientación usted mismo. (La orientation debe ser suficiente, pero a veces hay problemas en los que el evento no se dispara solo).

A continuación, saltar onCreate y en lugar de ello onConfigurationChanged se llama. Sobrescriba este método y aplique los cambios de diseño aquí. Si usted cambia su orientación linearLayouts aquí o si tiene un diseño personalizado de manejo de visualización para diferentes pantallas, depende de usted y depende de su implementación.

Animar será un poco más complicado, si es incluso possilbe. Una búsqueda rápida dice que no lo es .


Actualizar para comentar "Sólo quiero girar algunas vistas en lugar de girar el diseño"

En teoría , es posible crear su propio diseño y manejar el dibujo de las vistas de su hijo. Acabo de probarlo, pero no podía producir ningún resultado en un momento adecuado, pero lo que tendría que hacer:

  • Mantener sus últimos valores medidos utilizar etiquetas en la vista o enfoques similares para mantener las últimas medidas y diseños, de modo que después de la orientación puede cambiar
  • Esperan el cambio de orientación : desencadenar el dibujo girado – girar el lienzo, diseñar las vistas con las dimensiones anteriores y dibujar las vistas de los niños donde hubieran estado antes , y
  • Iniciar una animación interpolar del último a los nuevos valores, girar el lienzo del último al nuevo diseño

Así es como lo haría.

  • Android: orientación de la vista previa de la cámara en modo vertical
  • LibGDX texturepacker rotación
  • Gire ImageView en Android en un punto fijo con RotateAnimation
  • Rotar una superficie de la cámaraVer a retrato
  • Comportamiento extraño con el sensor de orientación de Android
  • Android, ayuda a girar la imagen en el tacto
  • ¿Por qué no funciona setVisibility después de animar una vista?
  • La música se detiene cuando la pantalla gira utilizando MediaPlayer en Android
  • Cómo girar un drawable con anti-aliasing habilitado
  • Traducción después de la rotación
  • ¿Cómo puedo detectar la rotación de la pantalla?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.