Cómo obtener NUEVA anchura / altura del diseño raíz en onConfigurationChanged?

Una de nuestras vistas tiene un ScrollView como su diseño raíz. Cuando se hace girar el dispositivo y se llama onConfigurationChanged() , nos gustaría poder obtener la nueva anchura / altura del ScrollView . Nuestro código se ve así:

 @Override public void onConfigurationChanged(Configuration newConfig) { Log.d(TAG, "Width: '" + findViewById(R.id.scrollview).getWidth() + "'"); Log.d(TAG, "Height: '" + findViewById(R.id.scrollview).getHeight() + "'"); super.onConfigurationChanged(newConfig); Log.d(TAG, "Width: '" + findViewById(R.id.scrollview).getWidth() + "'"); Log.d(TAG, "Height: '" + findViewById(R.id.scrollview).getHeight() + "'"); } 

La sección correspondiente de nuestro AndroidManifest.xml se ve así:

 <activity android:name=".SomeActivity" android:configChanges="keyboardHidden|orientation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter> </activity> 

Y, por último, la parte relevante de nuestro diseño se ve así:

 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollview" android:layout_height="fill_parent" android:layout_width="fill_parent" > <LinearLayout android:id="@+id/container" android:orientation="vertical" android:layout_height="fill_parent" android:minHeight="200dip" android:layout_width="fill_parent" > 

En nuestro Droid, esperábamos que el ancho de ScrollView pasara a 854 cuando se cambiara al paisaje ya 480 cuando cambiara de nuevo a vertical (y la altura haga el cambio equivalente, menos la barra de menús). Sin embargo, estamos viendo lo contrario. Aquí está nuestro LogCat:

 // Switching to landscape: 03-26 11:26:16.490: DEBUG/ourtag(17245): Width: '480' // Before super 03-26 11:26:16.490: DEBUG/ourtag(17245): Height: '778' // Before super 03-26 11:26:16.529: DEBUG/ourtag(17245): Width: '480' // After super 03-26 11:26:16.536: DEBUG/ourtag(17245): Height: '778' // After super // Switching to portrait: 03-26 11:26:28.724: DEBUG/ourtag(17245): Width: '854' // Before super 03-26 11:26:28.740: DEBUG/ourtag(17245): Height: '404' // Before super 03-26 11:26:28.740: DEBUG/ourtag(17245): Width: '854' // After super 03-26 11:26:28.740: DEBUG/ourtag(17245): Height: '404' // After super 

Claramente, estamos obteniendo las dimensiones de retrato cuando cambiamos a paisaje y las dimensiones de paisaje cuando cambiamos a retrato. ¿Hay algo que estamos haciendo mal? Podríamos obtener hacky y resolver esto, pero siento que hay una solución simple que nos falta.

GetWidth () devuelve el ancho como la vista se establece, lo que significa que debe esperar hasta que se dibuja a la pantalla. onConfigurationChanged se llama antes de volver a dibujar la vista para la nueva configuración y así no creo que pueda obtener su nuevo ancho hasta más tarde.

Para aquellos que buscan una descripción de la solución más detallada: Puede utilizar el ViewTreeObserver de su vista y registrar un OnGlobalLayoutListener .

 @Override public void onConfigurationChanged(Configuration newConfiguration) { super.onConfigurationChanged(newConfiguration); final View view = findViewById(R.id.scrollview); ViewTreeObserver observer = view.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Log.v(TAG, String.format("new width=%d; new height=%d", view.getWidth(), view.getHeight())); view.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } 

Cuando onGlobalLayout llamó no está seguro de que la vista se ha cambiado de tamaño de acuerdo con la nueva orientación de diseño, por lo que para mí sólo la siguiente solución funcionó correctamente:

 @Override public void onConfigurationChanged(Configuration newConfig) { final int oldHeight = mView.getHeight(); final int oldWidth = mView.getWidth(); mView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (mView.getHeight() != oldHeight && mView.getWidth() != oldWidth) { mView.getViewTreeObserver().removeOnGlobalLayoutListener(this); //mView now has the correct dimensions, continue with your stuff } } }); super.onConfigurationChanged(newConfig);} 
  • Android - EditText multilínea forzada a llenar la altura
  • Scrollview dentro de un fragmento de viewpager no se desplaza cuando se muestra el teclado
  • ¿Hay una manera de desplazarse mediante programación una vista de desplazamiento a un texto de edición específico?
  • Android ScrollView scrollTo () método no funciona con TextView?
  • Modo Android Landscape cortando mis botones en la parte superior
  • Android dificultad con linearlayout dentro de scrollview
  • Diseño relativo en ScrollView
  • Mi listview no rellena el padre
  • Android corta mi texto cuando usa fragmentos
  • No estirar ScrollView
  • ScrollView alawys desplazándose hacia abajo
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.