PreferenceFragment中的ActionBar不会重新计算高度和字体大小

时间:2014-11-02 22:02:43

标签: android android-actionbar android-orientation preferenceactivity android-appcompat

使用最新的AppCompat-v21库,我使用ActionBarActivity创建并填充PreferenceFragment。但是,当更改方向或屏幕大小时,ActionBar似乎不会更改高度和文本大小。对其他活动进行测试时,这种行为似乎只发生在PreferenceActivity中(与此处提出的问题相反:ActionBar capacity/overflow not changing on orientation change)。

首先,为了处理方向更改,我将android:configChanges="keyboard|keyboardHidden|orientation|screenSize"添加到Manifest。我怀疑这是导致此问题的主要原因,但正如我之前提到的,这适用于其他Activity

以下是一些解释此问题的屏幕截图:

在纵向模式下发布PreferenceActivity

Portrait start

从肖像旋转到风景:

rotate to landscape

以横向模式启动PreferenceActivity

landscape

从横向旋转为肖像:

rotate to portrait

其他信息

以下是PreferenceActivity类:

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class PrefsActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit();
    }

}

这种行为是个错误吗?如果没有,是否有解决方法或修复?

<小时/> 编辑我

我尝试使用新的ToolBar小部件,但没有运气。

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;

public class PrefsActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preference);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_pref);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        getFragmentManager().beginTransaction().replace(R.id.pref_frame, new PrefsFragment()).commit();
    }

}

3 个答案:

答案 0 :(得分:3)

建议不要

android:configChanges,因为方向,键盘不是活动娱乐的唯一原因。

因此,更好的方法是从Manifest中删除它,并在setRetainInstance(true);类上设置Fragment。这将绕过片段的破坏和重新创建循环,同时刷新活动。

由于Toolbar包含在Activity中而不包含在Fragment中,因此这将在保留Fragment的同时刷新工具栏。

如果是对话框,使用Fragment Lifecycle关闭/重新打开它们将会有效。

来源:http://developer.android.com/guide/topics/resources/runtime-changes.html

答案 1 :(得分:3)

我可以提供这个解决方案。

使用系统ActionBar,使用Lollipop工具栏和AppCompat工具栏。

public static void fixActionBar(Activity activity, View toolbar)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        if (toolbar == null)
        {
            int id = activity.getResources().getIdentifier("action_bar", "id", "android");
            if (id != 0) toolbar = (Toolbar) activity.findViewById(id);
        }
        if (toolbar != null)
        {
            Context context = toolbar.getContext();
            TypedArray typedArray = context.obtainStyledAttributes(new int[]
                    {android.R.attr.actionBarStyle, android.R.attr.actionBarSize});
            int actionStyle = typedArray.getResourceId(0, 0);
            int actionHeight = typedArray.getDimensionPixelSize(1, 0);
            typedArray.recycle();
            try
            {
                View container = (View) toolbar.getParent();
                Field field = container.getClass().getDeclaredField("mHeight");
                field.setAccessible(true);
                field.setInt(container, actionHeight);
                View overlay = (View) container.getParent();
                field = overlay.getClass().getDeclaredField("mActionBarHeight");
                field.setAccessible(true);
                field.setInt(overlay, actionHeight);
            }
            catch (Exception e)
            {

            }
            toolbar.getLayoutParams().height = actionHeight;
            toolbar.setMinimumHeight(actionHeight);
            typedArray = context.obtainStyledAttributes(actionStyle, new int []
                    {android.R.attr.titleTextStyle});
            ((Toolbar) toolbar).setTitleTextAppearance(context, typedArray.getResourceId(0, 0));
            typedArray.recycle();
        }
    }
}

从您的活动的onConfigurationChanged调用此方法。

答案 2 :(得分:0)

您测试过的其他活动是否也在清单上声明了android:configChanges

正如你所说,问题在于

android:configChanges="keyboard|keyboardHidden|orientation|screenSize"

不处理旋转。它实际上会停止重新创建活动和视图,导致视图在配置更改后不读取相应的值。

考虑到您使用的是片段,我会移除android:configChanges属性并让PrefsFragment保留其实例。