ActionBar в PreferenceActivity
![Example: Android Market]()
В моем приложении я использую образец совместимости с Action Bar от Google (расположенный в <sdk>/samples/android-<version>/ActionBarCompat
), который отлично работает. Единственная проблема, с которой я сталкиваюсь, - это применить это к моему PreferenceActivity
, чтобы получить экран, подобный настройкам в Android Market (см. Рисунок).
Чтобы заполнить ActionBar
значками, каждый Activity
должен расширить класс ActionBarActivity
. Проблема в том, что мой Activity
уже расширяет PreferenceActivity
, а в Java-классах не может распространяться более одного класса.
Должен быть способ получить ActionBar
вместе с PreferenceScreen
. Я был бы рад, если бы кто-нибудь мог предложить решение этой общей проблемы.
PS: Решение, подобное в Как добавить кнопку в PreferenceScreen, не подходит, потому что ActionBar
на самом деле является строкой заголовка, и это больше похоже на Java чем макет.
Ответы
Ответ 1
Изменить: Мой ответ ниже довольно взломан, и кажется, что он устарел (для Android 3.0). Посмотрите на другие ответы для менее хакерских и более современных решений. ~ pyko 2014- 09-01
Мне удалось заставить его работать - не уверен, что это самое приятное/чистое решение, но оно работает.
Пришлось внести следующие изменения:
-
Сделайте копию ActionBarActivity
и добавьте новый класс PreferenceActivity
public abstract class ActionBarPreferenceActivity extends PreferenceActivity {
// contents exactly the same as 'ActionBarActivity'
}
-
Немного измените onCreate()
в ActionBarHelperBase.java
- сделайте специальный случай для PreferenceActivity
классов
@Override
public void onCreate(Bundle savedInstanceState) {
// If the activity is a PreferenceActivity, don't make the request
if (!(mActivity instanceof PreferenceActivity)) {
mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
}
-
Расширьте свой класс PreferenceActivity и добавьте запрос для FEATURE_CUSTOM_TITLE
до, который вы вызываете super.onCreate()
public class MyPreferenceActivity extends ActionBarPreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // add this line
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
// etc etc
}
// etc etc
}
Насколько я могу судить, необходимы изменения 2 и 3, потому что для PreferenceActivity
:
"Как только вы вызовете super.onCreate(), будет создана группа ViewGroup, и поэтому вам не разрешено изменять параметры окна". (см. комментарий Оливера к ответу)
Я предполагаю, что порядок работы компонентов в действиях PreferenceActivity
отличается от обычных действий Activity
.
Ответ 2
Если вы хотите попробовать реализацию PreferenceFragment на основе фрагмента поддержки-v4:
https://github.com/kolavar/android-support-v4-preferencefragment
Я использую его сам, и это не очень помогает превратить PreferenceActivity в PreferenceFragment.
Ответ 3
Можете ли вы просто клонировать код для ActionBarActivity и изменить "extends Activity" на "extends PreferenceActivity"? Затем расширьте свой новый класс вместо ActionBarActivity.
Из всех приложений Google, которые я видел, кажется, необычно вводить кнопки в панели действий PreferenceActivity. Если вы не нажимаете на него кнопки, вы можете просто использовать ресурс альтернативного стиля значений-v11, чтобы показать голографическую тему, и установить этот стиль в манифесте для своей PreferenceActivity.
Ответ 4
Я использовал в своем приложении эту панель действий
https://github.com/johannilsson/android-actionbar, и он отлично работает с этим потоком Как добавить кнопку в PreferenceScreen
Ответ 5
Я хотел бы поблагодарить @pyko за отличный ответ, но у него есть проблема, что он не будет работать хорошо на HoneyComb и выше. хорошо, вы можете взломать способ получить его, как @AndroidDev сказал;
Но @pyko собирается загрязнить класс ActionBarHelperBase, а @AndroidDev не очень прозрачен. Лучший способ - создать ActionBarActivityPreferences, который распространяется из PreferenceActivity; и в методе onCreate измените порядок вызова родительского метода:
@Override
protected void onCreate(Bundle savedInstanceState) {
//IMPORTATNT: MAKE SURE actionBarHelper called before super;
//as super oncreate of prefenceactivity is actuallying setting the content view
mActionBarHelper.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
зачем вызывается "mActionBarHelper.onCreate(savedInstanceState)"; перед 'super.onCreate(savedInstanceState);', потому что super (т.е. PreferenceActivity) на самом деле устанавливает представление содержимого в свой метод onCreate, что вызовет сбой ( "requestFeature() должен быть вызван перед добавлением контента" ). Так что вам нужно сделать это, чтобы поменять порядок, сделать sure 'mActionBarHelper.onCreate(savedInstanceState);' вызывается перед супер.
Таким образом, нам не нужно загрязнять "ActionBarHelperBase", но мы сохраняем SettingActivity очень чистым, потому что мы инкапсулируем сложную деталь в "ActionBarActivityPreferences" и bang!
Ответ 6
Вы можете легко добавить панель действий в действие предпочтения с помощью следующих изменений:
В AndroidManifest.xml:
<activity
android:name=".activity.SettingsActivity"
android:theme="@style/SettingsTheme"
android:label="Settings"/>
В v21/styles.xml
<style name="SettingsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar">
<item name="android:colorPrimary">@color/colorPrimary</item>
<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
</style>
В v14/styles.xml для поддержки Back API:
<style name="SettingsTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">@style/ActionBar.V14.Movie.NoTitle</item>
</style>
Ответ 7
Спасибо, просто обновление, вам нужно добавить оператор if перед строкой Custom Title для поддержки HoneyComb и выше.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
Ответ 8
Вы можете получить ActionBarSherlock lib и позволить коду расширять SherlockPreference;