Настройки Часть Android Jetpack .

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

Чтобы интегрировать настраиваемые пользователем параметры в ваше приложение, используйте библиотеку настроек AndroidX. Эта библиотека управляет пользовательским интерфейсом и взаимодействует с хранилищем, поэтому вы определяете только отдельные параметры, которые может настроить пользователь. Библиотека поставляется с темой Material Design, которая обеспечивает единообразный пользовательский интерфейс на всех устройствах и версиях ОС.

Начать

Preference — это основной строительный блок библиотеки предпочтений. Экран настроек содержит иерархию Preference . Вы можете определить эту иерархию как ресурс XML или построить иерархию в коде .

В следующих разделах описывается, как создать простой экран настроек с использованием библиотеки настроек AndroidX.

Прежде чем начать, добавьте зависимость библиотеки предпочтений в файл build.gradle :

dependencies {
    implementation
"androidx.preference:preference-ktx:1.2.0"
}
dependencies {
    implementation
("androidx.preference:preference-ktx:1.2.0")
}

После синхронизации Gradle вы можете перейти к XML-части задачи.

Создайте иерархию

В своем проекте перейдите в папку res/xml , создайте файл preferences.xml и добавьте в него следующий код:

<PreferenceScreen
   
xmlns:app="http://schemas.android.com/apk/res-auto">

   
<SwitchPreferenceCompat
       
app:key="notifications"
       
app:title="Enable message notifications"/>

   
<Preference
       
app:key="feedback"
       
app:title="Send feedback"
       
app:summary="Report technical issues or suggest new features"/>

</PreferenceScreen>

Эта иерархия содержит два объекта Preference : SwitchPreferenceCompat , который позволяет пользователям включать и выключать настройку, и базовое Preference без виджета.

При построении иерархии каждое Preference должно иметь уникальный ключ.

Раздувайте иерархию

Чтобы раздуть иерархию из атрибута XML, создайте PreferenceFragmentCompat , переопределите onCreatePreferences() и предоставьте XML-ресурс для раздувания, как показано в следующем примере:

class MySettingsFragment : PreferenceFragmentCompat() {
   
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource
(R.xml.preferences, rootKey)
   
}
}
public class MySettingsFragment extends PreferenceFragmentCompat {
   
@Override
   
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource
(R.xml.preferences, rootKey);
   
}
}

Затем вы можете добавить этот Fragment в свою Activity , как и любой другой Fragment :

class MySettingsActivity : AppCompatActivity() {
   
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
        supportFragmentManager
               
.beginTransaction()
               
.replace(R.id.settings_container, MySettingsFragment())
               
.commit()
   
}
}
public class MySettingsActivity extends AppCompatActivity {
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        getSupportFragmentManager
()
               
.beginTransaction()
               
.replace(R.id.settings_container, new MySettingsFragment())
               
.commit();
   
}
}

Результат показан на следующем изображении:

Изображение, показывающее пример экрана предпочтений.
Рис. 1. Экран настроек, созданный с использованием двух объектов Preference .

Следите за предпочтениями

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

findPreference<SwitchPreferenceCompat>("notifications")
   
?.setOnPreferenceChangeListener { _, newValue ->
       
Log.d("Preferences", "Notifications enabled: $newValue")
       
true // Return true if the event is handled.
   
}

findPreference
<Preference>("feedback")
   
?.setOnPreferenceClickListener {
       
Log.d("Preferences", "Feedback was clicked")
       
true // Return true if the click is handled.
   
}
SwitchPreferenceCompat notificationsPref = findPreference("notifications");

if (notificationsPref != null) {
    notificationsPref
.setOnPreferenceChangeListener((preference, newValue) -> {
       
Log.d("Preferences", String.format("Notifications enabled: %s", newValue));
       
return true; // Return true if the event is handled.
   
});
}

Preference feedbackPref = findPreference("feedback");

if (feedbackPref != null) {
    feedbackPref
.setOnPreferenceClickListener((preference) -> {
       
Log.d("Preferences", "Feedback was clicked");
       
return true; // Return true if the event is handled.
   
});
}

Прочитать текущее значение предпочтения

PreferenceFragmentCompat скрывает большую часть механизмов, участвующих в сохранении и чтении настроек. Однако все хранится с помощью SharedPreferences , и вы можете прочитать эти значения, как обычно это делаете с SharedPreferences :

val preferences = PreferenceManager.getDefaultSharedPreferences(this).all

preferences
.forEach {
   
Log.d("Preferences", "${it.key} -> ${it.value}")
}
var preferences = PreferenceManager.getDefaultSharedPreferences(context).getAll();

preferences
.forEach((key, value) ->{
   
Log.d("Preferences", String.format("%s -> %s", key, value));
});

Предыдущий фрагмент получает экземпляр SharedPreferences по умолчанию для приложения, получает доступ ко всем сохраненным значениям, циклически обрабатывает их и печатает их в Logcat.