在更改PreferenceScreen时保持显示的操作栏

我正在尝试在我的首选项屏幕上显示一个操作栏。 为了做到这一点,我在我的设置活动中添加了以下代码

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

那么我的代码的其余部分在PreferencesFragment中。 这工作正常,但只要按下PreferenceScreen首选项,操作栏是隐藏的。 如果我回到首选主屏幕,我可以再次看到它。 任何想法如何保持操作栏显示(并用PreferenceScreen标签更新)?

编辑:查看PreferenceScreen代码,它看起来像是一个全屏的对话框,当PreferenceScreen被点击时打开。 因为我的偏好有一个标题,对话框应该显示一个标题,但它不

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

Solutions Collecting From Web of "在更改PreferenceScreen时保持显示的操作栏"

我终于设法find了一个方法来做到这一点。 这是一种丑陋的,但它的作品。

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

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

顺便说一句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> 

我在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(); } 

最后,我在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); } } 

有同样的问题。 嵌套的PreferenceScreen没有一个ActionBar。 遍历代码后,它似乎是由AppCompatActivityPreferenceScreen之间的冲突造成的。

一方面, AppCompatActivity提供了自己的操作栏,因此需要一个从Theme.AppCompat降序的主题,它指定了Theme.AppCompat windowNoTitle = true地方(不能确切地指出在哪里)。 另一方面, PreferenceScreen使用活动主题(而不是子主题,例如dialogTheme )的平台Dialog 。 可能是一个错误。

如果你不关心Theme.AppCompat ,下面是一个适用于API 21+的简单解决方法:

  • 使用android.preference.PreferenceActivity作为您的活动的基类
  • 为该活动创build一个主题:

     <!-- 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> 
  • AndroidManifest.xml为此活动指定android:theme="@style/PreferenceTheme"

你会得到更像是一个标准的窗口标题,而不是一个完整的ActionBar。 我还没有想出如何添加工作返回button,等等。

如果要保持与AppCompatActivity和相关主题的兼容性,则需要在活动窗口上请求FEATURE_NO_TITLE 。 否则,您将在顶级PreferenceScreen结束两个操作栏(内置顶层,底层支持)。

由于谷歌到目前为止可悲的没有解决它,实际上有一个更容易的解决scheme:

  1. 将您的SettingsActivity类设置为仅从“活动”扩展。

    public class SettingsActivity extends Activity { ...

  2. 在SettingsActivty的v21 / styles文件夹中创build一个新的主题,并将父项设置为“Theme.Material。*”

    <style name="CustomThemeSettings" parent="android:Theme.Material"> <item name="android:colorPrimary">@color/...</item> <item name="android:colorPrimaryDark">@color/...</item> <item name="android:colorAccent">@color/...</item> </style>

  3. 在Manifest.xml文件中设置新的主题:

    <activity android:name=".SettingsActivity" android:label="@string/title_activity_settingsactivity" android:theme="@style/CustomThemeSettings" > </activity>

  4. 它只是工作:)

  5. (可选)如果您想为旧设备提供Material Design支持
    您可以将SettingsActivity放置在v21 +文件夹中,并为具有父AppCompat的旧设备创build其他SettingsActivity。

我做了一个应用程序,在首选项活动中有一个操作栏。 我似乎无法看到这样做的关键,虽然我记得我花了一些时间来正确的。

我们的代码似乎很相似。 唯一引起我注意的是这个导入: import android.support.v7.app.ActionBarActivity;

让我知道这是否有帮助

 public class SettingsActivity extends ActionBarActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment() ).commit(); } // End of onCreate static public class PrefsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); // Load the preferences from an XML resource } } // end of PrefsFragment } 

另外:你的styles.xml中有这个吗?

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> </style> 

但只要按下PreferenceScreen首选项,操作栏就会隐藏起来。 如果我回到首选主屏幕,我可以再次看到它。

我猜你会在点击偏好时启动一项新的活动

您的偏好片段应该看起来像这样

  public static class PreferencesFragment extends PreferenceFragment { public PlaceholderFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.your_preferences); } } 

然后如下所示对your_preferences进行抽样

 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" > <PreferenceCategory android:title="@string/pref_category_title"> <PreferenceScreen android:title="@string/title" android:summary="@string/summary"> <intent android:targetClass="com.your.package.Youractivity " android:targetPackage="com.your.package"/> </PreferenceScreen> <PreferenceScreen android:title="@string/another_title"> <intent android:targetClass="com.your.package.activity2" android:targetPackage="com.your.package.activity"/> </PreferenceScreen> </PreferenceCategory> 

最后,Youractivity应该从ActionBarActivity扩展主要的东西

  public class Youractivity extends ActionBarActivity { } 

上面的代码适用于我。

正如你在问题中提到的那样,全屏的Dialog可能是一个问题。

尝试将Dialog样式更改为:

 <style name="Theme.Holo.Dialog"> 

或具有以下属性的样式:

 <item name="windowActionBar">true</item> <item name="windowNoTitle">false</item> 

在这里你可以阅读如何获得Dialog参考。

注意:仅适用于API> = 14

Source1和Source2

PreferenceActivity1.java

 public class PreferenceActivity1 extends android.preference.PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pref1); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } } 

PreferenceActivity2.java

 public class PreferenceActivity2 extends android.preference.PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pref2); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } } 

settings_toolbar.xml(布局)

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" app:navigationContentDescription="@string/abc_action_bar_up_description" android:background="?attr/colorPrimary" app:navigationIcon="?attr/homeAsUpIndicator" app:title="@string/app_name" /> 

pref1.xml(XML)

 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:theme="@android:style/Theme.Light" > <PreferenceCategory android:title="Main Preferences" > <CheckBoxPreference android:key="wifi enabled" android:title="WiFi" /> </PreferenceCategory> <PreferenceScreen android:key="key1" android:summary="" android:title="Wifi Settings" > <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.PreferenceActivity2" android:targetPackage="com.example" /> </PreferenceScreen> </PreferenceScreen> 

pref2.xml(XML)

 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:theme="@android:style/Theme.Light" > <PreferenceCategory android:title="Wifi Settings" > <CheckBoxPreference android:key="prefer wifi" android:title="Prefer WiFi" /> </PreferenceCategory> </PreferenceScreen> 

performance

 <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name="com.example.PreferenceActivity1" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.PreferenceActivity2" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> 

结果
在这里输入图像说明
在这里输入图像说明