Для упрощения работы с группой настроек 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.