Как использовать библиотеку поддержки предпочтений v7/v14?

Вместе с релизом M появляются новые библиотеки поддержки. Один из них, который кажется очень полезным, это библиотека v7 Preference Support.

Кажется, что у него PreferenceActivity или что-то подобное, как мы его интегрируем в наше приложение?

Ответ 1

Вам нужно расширить AppCompatActivity, который требуется для фрагмента, и включить подкласс PreferenceFragmentCompat. Абстрактный фрагмент требует переопределения одного метода, в котором вы должны поместить свою логику инфляции предпочтений. И, наконец, ваша тема активности должна указывать атрибут preferenceTheme.

Прочтите объявление здесь. В библиотеке preference-v7 вы можете заменить PreferenceFragment (API 11+) подклассом PreferenceFragmentCompat и SwitchPreference (API 14+) на SwitchPreferenceCompat и работать с настройками экрана с API 7.

Ниже приводится описание того, как я сделал это:

SettingsActivity.java

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);
    }
}

макет /activity _settings.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent" >
    <fragment
        android:name=".SettingsFragment"
        android:tag=".SettingsFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

SettingsFragment.java

public class SettingsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle bundle, String s) {
        addPreferencesFromResource(R.xml.preferences);
    }
}

XML/preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <android.support.v7.preference.PreferenceCategory
        ...>

        <android.support.v7.preference.ListPreference
            ... />

        <android.support.v7.preference.SwitchPreferenceCompat
            ... />

        ...

    </android.support.v7.preference.PreferenceCategory>

    ...

</android.support.v7.preference.PreferenceScreen>

<сильные > значения /styles.xml

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
    ...
</style>

тема по умолчанию-v7 по умолчанию

<style name="PreferenceThemeOverlay">
    <item name="preferenceScreenStyle">@style/Preference.PreferenceScreen</item>
    <item name="preferenceFragmentStyle">@style/PreferenceFragment</item>
    <item name="preferenceCategoryStyle">@style/Preference.Category</item>
    <item name="preferenceStyle">@style/Preference</item>
    <item name="preferenceInformationStyle">@style/Preference.Information</item>
    <item name="checkBoxPreferenceStyle">@style/Preference.CheckBoxPreference</item>
    <item name="switchPreferenceCompatStyle">@style/Preference.SwitchPreferenceCompat</item>
    <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item>
    <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item>
    <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList</item>
</style>

Ответ 2

С новой библиотекой поддержки v7 вы можете использовать PreferenceFragmentCompat с любыми Activity или AppCompatActivity

public static class PrefsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
}

Вы должны установить preferenceTheme в своей теме:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  ...
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

Таким образом вы можете настроить preferenceTheme для стилей макетов, используемых для каждого типа предпочтений, без влияния на другие части вашей деятельности.

Ответ 3

Ответ hidro прав, но еще одно замечание:

Просто используйте обычные теги xml, например PreferenceScreen вместо полного имени класса. Библиотека поддержки автоматически преобразует их.

Почему: Если вы используете полное имя класса, предложение кода и предварительный просмотр макета не будут работать должным образом.

Итак, вы должны написать xml следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory
        ...>

        <ListPreference
            ... />

        <SwitchPreferenceCompat
            ... />

        ...

    </PreferenceCategory>

    ...

</PreferenceScreen>

Ответ 4

Вы правы, он не существует в appcompat v7, но Google фактически добавил AppCompatDelegate абстрактный класс в качестве делегата, который вы можете использовать для поддержки поддержки AppCompat для любой активности. Вы можете найти более этот ответ.

Это пример того, как вводить AppCompatDelegate в свою деятельность из образцов AppCompat из Google, вы можете найти здесь здесь.

Ответ 5

Я попытался реализовать ответ Hidro выше с активностью, которая также содержала панель инструментов, и это дало мне следующее исключение разметки компоновки из-за следующей ошибки:

Вызвано: java.lang.NullPointerException: попытка вызвать виртуальную метод     'android.content.Context android.support.v4.app.FragmentHostCallback.getContext()'     по ссылке нулевого объекта

Я не смог их решить, поэтому прибегнул к следующему:

public class SettingsActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  if(savedInstanceState == null)
    getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new SettingsFragment()).commit();
  }
}

Со следующей компоновкой для параметра SettingsActivity:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:fitsSystemWindows="true">
  <include layout="@layout/toolbar"/>
  <FrameLayout android:id="@+id/fragment_container"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>

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