Для упрощения работы с группой настроек Android предоставляет специальный тип фрагмента - PreferenceFragmentCompat. Рассмотрим как ее использовать.
Создадим новый проект и вначале определим в файле build.gradle нужные зависимости для работы с PreferenceFragmentCompat:
implementation "androidx.fragment:fragment:1.3.6" implementation "androidx.preference:preference:1.1.1"
Для определения настроек добавим в папку res подпапку xml.
Затем в папку res/xml добавим новый файл, который назовем settings.xml. И изменим его следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:key="login"
android:summary="Введите логин"
android:title="Логин" />
<CheckBoxPreference
android:key="enabled"
android:summary="Отображать логин"
android:title="Отображать" />
</PreferenceScreen>
Здесь в корневом элементе PreferenceScreen устанавливаются элементы EditTextPreference и CheckBoxPreference. Через каждый из этих элементов мы можем взаимодействовать с определенной настройкой.
Вобще в данном случае мы можем использовать ряд различных типов настроек:
EditTextPreference: используется элемент EditText для ввода текстового значения
CheckBoxPreference: используется элемент CheckBox для установки логических значений true или false
SwitchPreference: используется элемент Switch для установки логических значений true или false ("on" и "off")
RingtonePreference: использует диалоговое окно для установки рингтона из списка рингтонов для установки логических значений true или false
ListPreference: использует список для выбора одного из предопределенных значений
MultiSelectListPreference: также использует список для выбора значений, но позволяет выбрать несколько элементов
Для каждого элемента настройки необходимо определить, как минимум, три атрибута:
android:key: устанавливает ключ настройки в SharedPreferences
android:title: название настройки для пользователя
android:summary: краткое описание по данной настройке для пользователя
Далее добавим новый класс Java, который назовем SettingsFragment:
package com.example.settingsapp;
import android.os.Bundle;
import androidx.preference.PreferenceFragmentCompat;
public class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.settings);
}
}
Фрагмент SettingsFragment наследуется от класса PreferenceFragmentCompat. В его методе onCreatePreferences вызывается метод
addPreferencesFromResource(), в который передается id ресурса xml с настройками (в данном случае ранее определенный ресурс R.xml.settings).
И теперь добавим в проект специальную activity для установки настроек. Назовем ее SettingsActivity. В итоге проект будет выглядеть следующим образом:
В файле layout для SettingsActivity - activity_settings.xml пропишем следующий интерфейс:
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/settings_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Здесь определен FragmentContainerView с id = settings_container - именно тот элемент, в который будет загружаться фрагмент SettingsFragment.
В коде SettingsActivity определим загррузку фрагмента:
package com.example.settingsapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, new SettingsFragment())
.commit();
}
}
SettingsActivity в качестве разметки интерфейса будет использовать ресурс R.layout.activity_settings.
При запуске SettingsActivity будет загружать фрагмент SettingsFragment в элемент с id settings_container.
Далее перейдем к главной activity - MainActivity. В файле activity_main.xml определим текстовое поле и кнопку:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/settingsText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@id/settingsButton"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/settingsButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Настройки"
android:onClick="setPrefs"
app:layout_constraintTop_toBottomOf="@id/settingsText"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
И изменим класс MainActivity:
package com.example.settingsapp;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView settingsText;
boolean enabled;
String login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
settingsText = findViewById(R.id.settingsText);
}
@Override
public void onResume() {
super.onResume();
SharedPreferences prefs= PreferenceManager.getDefaultSharedPreferences(this);
enabled = prefs.getBoolean("enabled", false);
login = prefs.getString("login", "не установлено");
settingsText.setText(login);
if(enabled)
settingsText.setVisibility(View.VISIBLE);
else
settingsText.setVisibility(View.INVISIBLE);
}
public void setPrefs(View view){
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
}
}
В методе onResume() получаем все настройки. Если настройка enabled равно true, то отображаем текстовое поле с логином.
В методе setPrefs(), который срабатывает при нажатии на кнопку, выполняется переход к SettingsActivity.
При первом запуске настроек не будет, и логин не будет отображаться. Перейдем на страницу настроек и установим там логин и включим его отображение, а затем вернемся на главную activity:
При этом вручную нам ничего не надо сохранять, все настройки автоматически сохраняются функционалом PreferenceFragmentCompat.