Ответ 1
Решение 1: Нативный PreferenceFragment
с AppCompatActivity
В AndroidStudio выберите "Файл" > "Создать проект"... > "Настройки". Этот шаблон использует обходной путь, который модифицирует нативный PreferenceFragment
для работы с AppCompatActivity
, похожим на support.v4.Fragment
или support.v7.PreferenceFragmentCompat
.
- Pro: теперь вы можете использовать встроенную функцию Предпочтения в пределах
AppCompat
приложение. Это быстрый подход при использовании шаблона AS, и вы можете придерживаться существующих документов и рабочих процессов Preference. - Con: переоснащение не очень интуитивно понятное или чистое. Кроме того, поскольку обычно рекомендуется использовать поддерживающие библиотеки там, где это возможно, я не уверен, насколько перспективен этот подход.
Решение 2: support.v7.preference.PreferenceFragmentCompat
с AppCompatActivity
- Pro: максимизирует совместимость
- Con: много пробелов, которые нужно преодолеть. Также это может не работать с любыми существующими расширениями-расширениями-расширениями там (например.
ColorPicker
илиFontPreferences
).
Если вы решите не использовать решение 1 (я все еще не уверен, какой из двух является более надежным будущим), при использовании support.v7.preference
существует несколько недостатков.
Ниже приводятся важные недостатки использования решения 2.
Зависимости:
dependencies {
...
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:preference-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
}
Тема:
Вам нужно будет определить preferenceTheme
в вашем файле styles.xml, иначе запуск приложения приведет к возникновению исключения.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
Возможно, вы захотите разделить его на разные стили для 7 +/14 +/21+. Многие люди жалуются на то, что это было ошибкой на момент написания этой статьи. Здесь есть исчерпывающий ответ .
Изменения поведения:, используя собственные настройки, очень просто: все, что вам нужно сделать, это определить/сохранить preferences.xml
и использовать addPreferencesFromResource(R.xml.preferences)
в вашем PreferenceFragment
. Пользовательские настройки легко выполняются путем подклассификации DialogPreference
, а затем просто ссылаются на preferences.xml
... bam, работает.
К сожалению, у support.v7.preference
было все, что связано с устранением Fragment
, что избавило его от многих встроенных функций. Вместо того, чтобы просто поддерживать XML, теперь вам приходится подклассифицировать и переопределять многие вещи, все из которых, к сожалению, недокументированы.
PreferenceScreens: PreferenceScreens
больше не управляются инфраструктурой. Определение PreferenceScreen
в вашем preference.xml
(как описано в docs) будет отображать запись, но при нажатии на нее ничего не происходит. Теперь вам решать, как отображать и перемещать суб-экраны. Скучный.
Существует один подход (описанный здесь), добавив PreferenceFragmentCompat.OnPreferenceStartScreenCallback
к вашему PreferenceFragmentCompat
. Хотя этот подход быстро реализуется, он просто меняет содержание существующего фрагмента предпочтений. Недостаток: нет обратной навигации, вы всегда "наверху", что не очень интуитивно для пользователя.
В другом подходе (описанном здесь) вам также понадобится управлять задним стеком, чтобы добиться обратной навигации, как ожидалось. Это использует preferenceScreen.getKey()
в качестве корня для каждого вновь созданного/отображаемого фрагмента.
При этом вы можете также наткнуться на PreferenceFragments
, который будет прозрачным по умолчанию и добавит странно друг к другу. Люди склонны переопределять PreferenceFragmentCompat.onViewCreated()
, чтобы добавить что-то вроде
// Set the default white background in the view so as to avoid transparency
view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.background_material_light));
Custom DialogPreference:. Ваши собственные предпочтения также перешли от тривиального к скучному. DialogPreference
теперь имеет все, что связано с фактическим диалогом, удалено. Этот бит теперь живет в PreferenceDialogFragmentCompat
. Таким образом, вам придется подклассы обоих, а затем займитесь созданием диалога и его отображением самостоятельно (пояснил здесь).
Глядя на источник PreferenceFragmentCompat.onDisplayPreferenceDialog()
показывает, что он знает, как иметь дело с ровно двумя настройками диалога (EditTextPreference
, ListPreference
), все остальное, что вам нужно реализовать с помощью OnPreferenceDisplayDialogCallback
s... кто-то задается вопросом, почему нет функции для обработки подкласса DialogPreference
!
Вот некоторый код, который реализует большинство этих обходных решений и помещает их в модуль lib:
https://github.com/mstummer/extended-preferences-compat.git
Основные намерения были:
- Удалите необходимость расширения и скрипта с помощью
Activity
иPreferenceFragment
в каждом приложении/проектах.preference.xml
теперь снова является единственным файлом для каждого проекта для изменения/поддержки. - Обработайте и покажите
PreferenceScreens
(подэлементы), как ожидалось. - Un-split
DialogPreference
для восстановления собственного поведения. - Ручка и отображение любого подкласса
DialogPreference
.
Не считайте его достаточно чистым, чтобы его можно было просто использовать из коробки, но он может дать вам несколько советов при работе с подобными проблемами. Дайте ему вращение и сообщите мне, есть ли у вас какие-либо предложения.