如何在onConfigurationChanged中获取根布局的新宽度/高度?

时间:2010-03-26 16:00:44

标签: android orientation scrollview onconfigurationchanged

我们的一个观点的根布局有ScrollView。当设备旋转并调用onConfigurationChanged()时,我们希望能够获得ScrollView的新宽度/高度。我们的代码如下所示:

@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() + "'");
}

我们的AndroidManifest.xml的相关部分如下所示:

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

最后,我们布局的相关部分如下所示:

<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"
        >

在我们的Droid上,我们希望看到ScrollView的宽度在切换到横向时变为854,在切换回纵向时变为480(并且高度为等效开关,减去菜单栏)。但是,我们正好相反。这是我们的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

显然,当我们切换到横向时,我们会获得纵向尺寸,而当我们切换到纵向时,我们会获得横向尺寸。有什么我们做错了吗?我们可以得到hacky并解决这个问题,但我觉得我们缺少一个简单的解决方案。

3 个答案:

答案 0 :(得分:36)

对于那些寻求更详细解决方案说明的人:您可以使用视图的ViewTreeObserver并注册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);
        }
    });
}

答案 1 :(得分:13)

当onGlobalLayout调用时,它不确定视图是否已根据新的布局方向调整大小,所以对我来说只有以下解决方案正常工作:

@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);}

答案 2 :(得分:7)

getWidth()在View布局时返回宽度,这意味着您需要等到它被绘制到屏幕上。在重新绘制新配置的视图之前调用onConfigurationChanged,因此我认为您不能在以后获得新的宽度。