При отображении экрана PreferenceScreen следует отображать панель действий
Я пытаюсь отобразить панель действий на экране настроек.
Для этого я добавил следующий код в свой параметр 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);
}
Ответы
Ответ 1
Наконец-то мне удалось найти способ сделать это.
Это отвратительно, но оно работает.
Сначала я добавляю тот же Intent к каждому определению PreferenceScreen в файле preferences.xml(обязательно обновите значение дополнительного параметра)
<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>
BTW 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);
}
}
Ответ 2
Была та же проблема. Вложенный PreferenceScreen
не имеет 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>
- укажите
android:theme="@style/PreferenceTheme"
для этого действия в AndroidManifest.xml
То, что вы получите, больше похоже на стандартный заголовок окна, чем полный ActionBar. Я еще не понял, как добавить кнопку "назад" и т.д.
Если вы хотите оставаться совместимым с AppCompatActivity
и связанными с ним темами, вам нужно запросить FEATURE_NO_TITLE
в окне активности. В противном случае на верхнем уровне PreferenceScreen
вы получите две панели действий (встроенная сверху и поддержка внизу).
Ответ 3
Так как Google грустно не исправлял его до сих пор, на самом деле существует гораздо более простое решение:
-
Установите класс SettingsActivity для расширения только из "Activity".
public class SettingsActivity extends Activity { ...
-
Создайте новую тему в папке 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>
-
Задайте новую тему в файле Manifest.xml:
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settingsactivity"
android:theme="@style/CustomThemeSettings" >
</activity>
-
Он просто работает:)
-
(Необязательно) Если вы хотите предоставить поддержку Material Design для более старых устройств
вы можете поместить параметр SettingsActivity в папку v21 + и создать другую
SettingsActivity для старых устройств с родительским AppCompat.
Ответ 4
Я сделал приложение, которое имеет панель действий в активности настроек. Кажется, я не вижу ключа к этому, хотя помню, мне потребовалось некоторое время, чтобы прибить его правильно.
Похоже, что наши коды очень похожи. Единственное, что попадает на мое внимание, это импорт: 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
}
Дополнение: есть ли у вас это в ваших стилях .xml?
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
</style>
Ответ 5
но как только я нажимаю на предпочтение 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 {
}
Этот код работает для меня.
Ответ 6
Как вы упомянули в вопросе, полноэкранный Dialog
может быть проблемой.
Попробуйте изменить стиль Dialog
на:
<style name="Theme.Holo.Dialog">
или стиль, который имеет следующие свойства:
<item name="windowActionBar">true</item>
<item name="windowNoTitle">false</item>
Здесь вы можете прочитать, как получить ссылку на Dialog
.
Ответ 7
Примечание. Только для 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>
Результат
![enter image description here]()
![enter image description here]()