更改PreferenceScreen时,请保持操作栏显示

use*_*605 18 android preferenceactivity android-actionbar preferencefragment

我正在尝试在我的首选项屏幕中显示操作栏.为此,我在SettingActivity中添加了以下代码

public class PreferencesActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.preferences_activity);
        getFragmentManager().beginTransaction()
                .replace(R.id.container, new PreferencesFragment()).commit();

            getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_HOME_AS_UP);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是我在PreferencesFragment中的其余代码.这样可以正常工作,但只要按下PreferenceScreen首选项,操作栏就会隐藏.如果我回到偏好主屏幕,我可以再次看到它.知道如何显示操作栏(并使用PreferenceScreen标签更新)吗?

编辑:查看PreferenceScreen代码,当单击PreferenceScreen时,它看起来像是一个全屏对话框.因为我的偏好有标题,所以Dialog也应该显示标题......但事实并非如此

    // Set the title bar if title is available, else no title bar
    final CharSequence title = getTitle();
    Dialog dialog = mDialog = new Dialog(context, context.getThemeResId());
    if (TextUtils.isEmpty(title)) {
        dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    } else {
        dialog.setTitle(title);
    }
Run Code Online (Sandbox Code Playgroud)

use*_*605 6

我终于设法找到了这样做的方法.这有点丑,但它确实有效.

首先,我将相同的Intent添加到我的preferences.xml文件中的每个PreferenceScreen定义中(确保更新额外参数的值)

        <PreferenceScreen
            android:key="pref1"
            android:summary="Summary1"
            android:title="Title1" >
            <intent
                android:action="android.intent.action.VIEW"
                android:targetPackage="my.package"
                android:targetClass="my.package.activity.PreferencesActivity" >
                <extra android:name="page" android:value="pref1" />
            </intent>
...

</PreferenceScreen>
Run Code Online (Sandbox Code Playgroud)

BTW my.package.activity.PreferencesActivity是我目前的偏好活动

然后我在Manifest中添加了一个intent-filter

        <activity
            android:name=".activity.PreferencesActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:label="@string/settings" >
            <intent-filter android:label="Pref" >
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.PREFERENCE" />
            </intent-filter>
  </activity>
Run Code Online (Sandbox Code Playgroud)

我在PreferenceActivity中添加了一些代码来处理这个问题

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

        this.fragment = new PreferencesFragment();
        this.fragment.setActivityIntent(getIntent());
        getFragmentManager().beginTransaction()
                .replace(R.id.container, this.fragment).commit();
    }
Run Code Online (Sandbox Code Playgroud)

最后,我在PreferencesFragment类中添加以下代码

    public void setActivityIntent(final Intent activityIntent) {
 if (activityIntent != null) {
                        if (Intent.ACTION_VIEW.equals(activityIntent.getAction())) {

                        if (intent.getExtras() != null) {
                            final String page = intent.getExtras().getString("page");
                            if (!TextUtils.isEmpty(page)) {
                                openPreferenceScreen(page);
                            }
                        }
                    }
    }

private void openPreferenceScreen(final String screenName) {
    final Preference pref = findPreference(screenName);
    if (pref instanceof PreferenceScreen) {
        final PreferenceScreen preferenceScreen = (PreferenceScreen) pref;
        ((PreferencesActivity) getActivity()).setTitle(preferenceScreen.getTitle());
        setPreferenceScreen((PreferenceScreen) pref);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 经过轻微修改后,这对我有用:在调用`onCreate()`之前,`PreferencesFragment`的'PreferenceManager`不会被创建,因此尝试查找并导航到`setActivityIntent()`中的正确屏幕将会失败.相反,我使用`setActivityIntent()`来提取和存储要使用的'PreferenceScreen`的名称,然后在`onCreate()`中调用`openPreferenceScreen()`来导航到它. (3认同)
  • 我提出了一个缺陷,请投票支持:https://code.google.com/p/android/issues/detail?id = 201377 (2认同)

szy*_*zym 6

有同样的问题.嵌套的PreferenceScreens没有ActionBar.单步执行代码后,它似乎是由AppCompatActivity和之间的冲突引起的PreferenceScreen.

一方面AppCompatActivity提供了自己的操作栏,因此需要一个主题下降的主题Theme.AppCompat指定windowNoTitle = true某处(无法准确指出位置).另一方面 - PreferenceScreen使用Dialog具有活动主题的平台(而不是子主题,例如dialogTheme).可能是一个错误.

如果您不关心Theme.AppCompat,这里有一个适用于API 21+的简单解决方法:

  • 使用android.preference.PreferenceActivity为您的活动的基类
  • 为该活动创建主题:

    <!-- This theme is used to show ActionBar on sub-PreferenceScreens -->
    <style name="PreferenceTheme" parent="">
      <item name="android:windowActionBar">true</item>
      <item name="android:windowNoTitle">false</item>
    </style>
    
    Run Code Online (Sandbox Code Playgroud)
  • 在.中指定android:theme="@style/PreferenceTheme"此活动AndroidManifest.xml

你会得到的更像是一个标准的窗口标题,而不是一个完整的ActionBar.我还没想出如何添加工作后退按钮等.

如果您想与AppCompatActivity相关主题保持兼容,则需要FEATURE_NO_TITLE在活动窗口中提出要求.否则,您最终会在顶层有两个操作栏(顶部内置,底部支撑)PreferenceScreen.