Панель действий в PreferenceActivity

Пример: Android Market

В своем приложении я использую новый образец совместимости панели действий от Google (расположенный по адресу <sdk>/samples/android-<version>/ActionBarCompat), который прекрасно работает. Единственная проблема, которая у меня есть, это применить это к моему PreferenceActivity, чтобы получить экран, похожий на настройки в Android Market (см. Рисунок).

Чтобы заполнить ActionBar иконками, каждый Activity должен расширять класс ActionBarActivity. Проблема в том, что мой Activity уже расширяет PreferenceActivity, а в классах Java нельзя расширять более одного класса.

Должен быть способ получить ActionBar вместе с PreferenceScreen. Я был бы рад, если бы кто-нибудь мог предоставить решение этой распространенной проблемы.

PS: Решение, подобное приведенному в разделе Как добавить кнопку в PreferenceScreen, работает не подходит, потому что ActionBar на самом деле является строкой заголовка, и поэтому это больше Java, чем макет.


person Matthias Robbers    schedule 28.10.2011    source источник
comment
Посмотрите эту ветку, я думаю, она вам поможет: stackoverflow.com/questions/2697233/ [1]: stackoverflow.com/questions/2697233/   -  person thalsharif    schedule 21.12.2011
comment
С большим количеством взломов и размышлений опытный программист мог бы это сделать. Я пробовал - не получилось.   -  person    schedule 14.03.2014
comment
У меня работает официальный PreferenceFragment!   -  person    schedule 16.03.2014
comment
Если хотите, вы можете попробовать библиотеку, которую я сделал: github.com/AndroidDeveloperLB/MaterialStuffLibrary   -  person android developer    schedule 15.11.2014


Ответы (8)


Редактировать: Мой ответ ниже довольно хакерский и кажется, что он сейчас устарел (для до Android 3.0). Посмотрите другие ответы для менее хакерских и более актуальных решений ~pyko 2014- 09–01


Мне удалось заставить его работать - не уверен, что это самое красивое/самое чистое решение, но оно работает.

Пришлось внести следующие изменения:

  1. Сделайте копию ActionBarActivity и добавьте новый класс PreferenceActivity

    public abstract class ActionBarPreferenceActivity extends PreferenceActivity {
        // contents exactly the same as 'ActionBarActivity'
    }
    
  2. Немного изменить 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);
        }
    
  3. Пусть ваша 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 действий.

person pyko    schedule 24.12.2011
comment
Спасибо за работу над этим. Кажется, что для этого нет чистого решения. Теперь я использую ActionBarSherlock для реализации панели действий, которая предоставляет гораздо больше функциональных возможностей, чем панель действий, совместимая с Android. - person Matthias Robbers; 02.02.2012
comment
Чтобы это заработало, мне пришлось проверить, была ли версия Android API ниже 3.0 (= 11), иначе это не сработало. Итак, в классе предпочтений я должен сделать это перед super.onCreate(...): if (ContextUtils.getAndroidApiVersion() ‹ OSContants.API.HONEYCOMB_3_0) { requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); // Для совместимости с панелью действий } - person dirkvranckaert; 11.05.2012
comment
Этого можно добиться, установив обычную панель действий, которая просто загружает PreferenceFragment. На случай, если кто-то еще попадет сюда, но не рассмотрел это простое решение. - person CQM; 17.03.2014
comment
Когда вы говорите «Создайте копию ActionBarActivity», вы имеете в виду взять исходный код и скопировать его в свой собственный проект? Например отсюда? android. googlesource.com/platform/frameworks/support/+/ - person Someone Somewhere; 06.04.2014
comment
Возможно, когда-то это работало, но с appcompat-v7_19.1.0 ActionBarActivity#onCreate вызывает ActionBarActivityDelegate.createDelegate((ActionBarActivity) this). Это означает, что вы не можете пройти в подкласс PreferenceActivity. - person William; 31.08.2014

Если вы хотите попробовать реализацию PreferenceFragment на основе фрагмента support-v4:

https://github.com/kolavar/android-support-v4-preferencefragment

Я использую его сам, и не так уж много работы по превращению PreferenceActivity в PreferenceFragment.

person Ostkontentitan    schedule 23.10.2013

Можете ли вы просто клонировать код для ActionBarActivity и изменить «extends Activity» на «extends PreferenceActivity»? Затем расширьте свой новый класс вместо ActionBarActivity.

Однако из всех приложений Google, которые я видел, размещение кнопок на панели действий PreferenceActivity кажется необычным. Если вы не размещаете на нем кнопки, вы можете просто использовать ресурс альтернативного стиля values-v11, чтобы отобразить голографическую тему, и установить этот стиль в манифесте для вашей PreferenceActivity.

person Tenfour04    schedule 05.11.2011
comment
Нет из-за ActionBarActivityDelegate - person ; 14.03.2014

Я использовал в своем приложении эту панель действий https://github.com/johannilsson/android-actionbar. и он отлично работает с этой веткой Как добавить кнопку в PreferenceScreen

person thalsharif    schedule 21.12.2011
comment
Спасибо. Теперь я использую ActionBarSherlock, что очень удобно. В первых версиях этой библиотеки в качестве основы использовалась панель действий Йоханнильссона. - person Matthias Robbers; 02.02.2012

Я хотел бы поблагодарить @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() должен быть вызван перед добавлением содержимого"). Итак, что вам нужно сделать, это поменять порядок, сделать конечно ' mActionBarHelper.onCreate(savedInstanceState);' вызывается перед super. Таким образом, нам не нужно загрязнять «ActionBarHelperBase», но мы сохраняем SettingActivity очень чистым, потому что мы инкапсулируем сложную деталь в «ActionBarActivityPreferences» и бах!

person tu0huang    schedule 19.07.2012

Вы можете легко добавить панель действий в действие предпочтений, внеся следующие изменения:

В 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>
person opticod    schedule 16.12.2016

Спасибо, просто обновление, вам нужно добавить оператор if перед строкой Custom Title для поддержки HoneyComb и выше.

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
   requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
person AndroidDev    schedule 09.04.2012

Вы можете получить библиотеку ActionBarSherlock и позволить коду расширять SherlockPreference;

person 王冰杰    schedule 24.04.2015