android - screenorientation - ¿Cómo obtener NUEVO ancho/alto del diseño de la raíz en onConfigurationChanged?
on rotate android (3)
Cuando onGlobalLayout llamó, no estoy seguro de que la vista haya cambiado de tamaño según la nueva orientación de diseño, por lo que para mí solo la solución que se muestra a continuació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);}
Una de nuestras vistas tiene un ScrollView
como su diseño raíz. Cuando se gira el dispositivo y se llama onConfigurationChanged()
, nos gustaría poder obtener el nuevo ancho / alto de 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 relevante 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, finalmente, 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 ver que el ancho de ScrollView pasara a 854 cuando se cambiara a horizontal, y a 480 cuando volviera a ser vertical (y la altura haría el cambio equivalente, menos la barra de menú). 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 ser intrépidos y resolver esto, pero siento que hay una solución simple que nos falta.
Para aquellos que buscan una descripción más detallada de la solución: Puede usar 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);
}
});
}
getWidth () devuelve el ancho a medida que se presenta la Vista, lo que significa que debe esperar hasta que se dibuje en la pantalla. Se llama a onConfigurationChanged
antes de volver a dibujar la vista para la nueva configuración, por lo que no creo que pueda obtener su nuevo ancho hasta más tarde.