18

我正在尝试在我的首选项屏幕中显示操作栏。为此,我在 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);
    }
}

然后是我在 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);
    }
4

8 回答 8

6

我终于设法找到了一种方法来做到这一点。这有点难看,但它有效。

首先,我在我的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 是我当前的偏好活动

然后我在清单中添加一个意图过滤器

        <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);
    }
}
于 2015-04-11T21:40:47.617 回答
6

有同样的问题。NestedPreferenceScreen没有 ActionBar。单步执行代码后,它似乎是由 和 之间的冲突引起AppCompatActivityPreferenceScreen

一方面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>
    
  • android:theme="@style/PreferenceTheme"_AndroidManifest.xml

你将得到的更像是一个标准的窗口标题,而不是一个完整的 ActionBar。我还没有弄清楚如何添加一个工作后退按钮等。

如果您想与相关主题保持兼容,AppCompatActivity则需要FEATURE_NO_TITLE在活动窗口中提出请求。否则,您最终会在顶层PreferenceScreen.

于 2016-03-20T16:39:31.937 回答
1

由于谷歌遗憾的是直到现在才修复它,实际上有一个更简单的解决方案:

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

    public class SettingsActivity extends Activity { ...

  2. 在 v21/styles 文件夹中为 SettingsActivty 创建一个新主题,并将父级设置为“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 的旧设备创建另一个 SettingsActivity。

于 2016-05-29T14:43:12.150 回答
0

正如您在问题中提到的,全屏Dialog可能是个问题。

尝试将Dialog样式更改为:

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

或具有以下属性的样式:

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

在这里您可以阅读如何获取对Dialog.

于 2015-04-09T18:58:02.727 回答
0

注意:仅适用于 API>=14

源 1源 2

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>

显现

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

结果
在此处输入图像描述
在此处输入图像描述

于 2015-04-09T20:22:15.893 回答
0

我制作了一个在首选项活动中确实有一个操作栏的应用程序。我似乎看不到这样做的关键,尽管我确实记得我花了一些时间才把它弄好。

看起来我们的代码很相似。唯一引起我注意的是这个导入: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>
于 2015-04-04T21:30:20.040 回答
0

但是只要我按下 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 {
}

上面的代码对我有用。

于 2015-04-09T15:08:40.200 回答
0

我创建PreferenceCompatActivity了一个兼容 AndroidX 的替代旧PreferenceActivity.

它在内部使用兼容片段。确保只使用androidx.preference.XXX类而不是类的导入android.preference.XXX

public class PreferenceCompatActivity extends AppCompatActivity implements AppCompatCallback, PreferenceFragmentCompat.OnPreferenceStartScreenCallback {

    private PreferenceFragmentCompat fragment;

    public void addPreferencesFromResource(@XmlRes int preferencesResId) {
        fragment = new RootPreferencesFragment(preferencesResId);
        getSupportFragmentManager().beginTransaction().replace(android.R.id.content, fragment).commitNow();
    }

    public PreferenceManager getPreferenceManager() {
        return fragment.getPreferenceManager();
    }

    public PreferenceScreen getPreferenceScreen() {
        return fragment.getPreferenceScreen();
    }

    public Preference findPreference(CharSequence key) {
        return fragment.findPreference(key);
    }

    @Override
    public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref) {
        LowerPreferencesFragment lowerFragment = new LowerPreferencesFragment(pref);
        getSupportFragmentManager().beginTransaction().replace(android.R.id.content, lowerFragment).addToBackStack("lower").commit();
        return true;
    }

    public static class RootPreferencesFragment extends PreferenceFragmentCompat {

        private int preferencesResId;

        public RootPreferencesFragment(int preferencesResId) {
            this.preferencesResId = preferencesResId;
        }

        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            addPreferencesFromResource(preferencesResId);
        }
    }

    public static class LowerPreferencesFragment extends PreferenceFragmentCompat {

        private PreferenceScreen prefs;

        public LowerPreferencesFragment() {
        }

        public LowerPreferencesFragment(PreferenceScreen prefs) {
            this.prefs = prefs;
        }

        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            if (prefs != null) {
                setPreferenceScreen(prefs);
                prefs = null;
            }
        }
    }
}

或者看到这个要点

于 2020-07-09T09:04:59.793 回答