Preference Screen (настройки приложения)

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

А нам, как разработчикам нам нужно найти самый простой и эффективный способ включения предпочтений в наше приложение. В этой статье мы создадим простой экран настройки, используя библиотеку настроек JetPack.

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

Разберемся на примере приложения с меню Настройки.

Создадим новый проект

Откройте Android Studio и выберите New Project -> Empty Activity в качестве шаблона проекта, а затем нажмите next. Дайте приложению любое имя. В моем случае я назову этот проект PreferencesScreen. Мы будем использовать Kotlin в качестве нашего языка программирования для этого проекта. Оставьте все остальное по умолчанию и нажмите Finish. Затем подождите несколько секунд, пока Android Studio создаст проект.

Добавим меню в MainActivity

Пункт меню нужен, чтобы перейти к экрану SettingActivity.

Чтобы добавить menu файл ресурсов, выполните следующие действия:
Щелкните правой кнопкой мыши по папке res, и выберите new -> Android resource file. Затем перейдите к файлу ресурсов Android, введите имя файла и тип ресурса, menu затем нажмите OK, чтобы закончить.

Внутри menu пакета выберите new -> menu resource файл, затем назовите его setting_menu и нажмите finish. Добавьте в settings_menu файл следующие строки кода:

<item
       android:id="@+id/setting"
       android:icon="@drawable/ic_settings"
       android:visible="true"
       android:contentDescription="@string/my_setting"
       app:showAsAction="ifRoom"
       android:title="@string/settings"/>

Чтобы меню было видно, добавьте в MainActivity.kt следующий код.

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.settings_menu, menu)
        return true
    }

Добавим Settings activity

На этом шаге мы добавим в проект шаблон активности Settings. 
Правой клавишей мыши щелкните по названию пакета и выберите:
New -> Activity -> Settings Activity

В результате в проект добавятся файлы:

  • SettingsActivity.kt – активность экрана Settings
  • settings_activity.xml – экран разметки, в котором будет только FrameLayout для вставки экрана с настройками. Такой вариант матрёшки нужен на случай если у вас появятся другие разметки экрана настроек.
  • root_preferences.xml – в этом экране как раз и хранятся все кнопочки экрана настроек.
  • arrays.xml – тут хранятся массивы и переменные необходимые для root_preferences.xml

Отредактируем файл arrays.xml

Давайте добавим свои параметры кнопочкам экрана настроек, отредактировав фал arrays.xml

<resources>
    <string-array name="theme_entries">
        <item>Светлая</item>
        <item>Тёмная</item>
        <item>Использовать системную тему</item>
    </string-array>

    <string-array name="theme_values">
        <item>1</item>
        <item>2</item>
        <item>3</item>
    </string-array>

    <string-array name="download_entries">
        <item>По умолчанию (100MB)</item>
        <item>1.0 MB</item>
        <item>4.7 MB</item>
        <item>10.6 MB</item>
        <item>32 MB</item>
        <item>50 MB</item>
        <item>Отключено</item>
    </string-array>

    <string-array name="download_values">
        <item>По умолчанию (100_mb)</item>
        <item>1.0_mb</item>
        <item>4.7_mb</item>
        <item>10.6_mb</item>
        <item>32_mb</item>
        <item>50_mb</item>
        <item>Отключено</item>
    </string-array>
</resources>

Это файл ресурсов. В нем есть несколько string-array – это массивы. Эти массивы мы присвоим элементам root_preferences.xml.

Отредактируем файл root_preferences.xml

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

    <PreferenceCategory
        app:icon="@drawable/ic_person_pin"
        app:title="Персональные">

        <EditTextPreference
            app:key="myEditText"
            app:title="Введите ваше имя"
            app:useSimpleSummaryProvider="true" />
        <CheckBoxPreference
            app:defaultValue="true"
            app:key="pref"
            app:summary="Check the text box if you like our design layout"
            app:title="Вам нравится приложение?" />
        <SeekBarPreference
            android:max="5"
            app:defaultValue="3"
            app:dependency="pref"
            app:icon="@drawable/ic_baseline_star"
            app:key="rating_bar"
            app:min="0"
            app:showSeekBarValue="true"
            app:summary="Оцените это приложение по шкале 0 -> 5"
            app:title="Оцените приложение" />

    </PreferenceCategory>

    <PreferenceCategory
        app:icon="@drawable/ic_baseline_color_lens"
        app:title="Основные">
        <ListPreference
            app:defaultValue="1"
            app:dialogTitle="Theme"
            app:entries="@array/theme_entries"
            app:entryValues="@array/theme_values"
            app:key="theme"
            app:title="Выберите тему"
            app:useSimpleSummaryProvider="true" />

    </PreferenceCategory>

    <PreferenceCategory
        app:icon="@drawable/ic_settings"
        app:title="Функции чата">
        <SwitchPreferenceCompat
            app:key="chat_features"
            app:summary="Используйте Wi-Fi или данные для обмена сообщениями, когда они доступны"
            app:title="Включить функции чата" />

        <SwitchPreferenceCompat
            app:dependency="chat_features"
            app:key="attachment"
            app:summaryOff="Сообщите другим, что вы прочитали их сообщение"
            app:summaryOn="Другие люди увидят, что вы автоматически прочитали их текст."
            app:title="Отправлять уведомления о прочтении" />
        <SwitchPreferenceCompat
            app:dependency="chat_features"
            app:key="attachment"
            app:summaryOff="Пусть другие знают, что вы печатаете"
            app:summaryOn="Другие люди будут видеть, когда вы печатаете"
            app:title="Показать индикаторы типа" />
        <ListPreference
            app:defaultValue="true"
            app:dependency="chat_features"
            app:entries="@array/download_entries"
            app:entryValues="@array/download_values"
            app:key="default(100_mb)"
            app:title="Автоматическая загрузка файлов, которые вы получаете через мобильные данные"
            app:useSimpleSummaryProvider="true" />

    </PreferenceCategory>

    <PreferenceCategory
        app:icon="@drawable/ic_read_more"
        app:title="Другие">
        <Preference
            android:summary="Это все, что у нас было на сегодня. Не стесняйтесь добавлять дополнительные настройки Android в свое приложение, прежде чем мы встретимся в следующий раз. Спасибо."
            app:title="Настройки Android" />
    </PreferenceCategory>

</PreferenceScreen>

Давайте немного разберемся:

  • PreferenceCategory – этот групповой элемент объединяет другие элементы в общую категорию и присваивает этой категории имя.
  • EditTextPreference – предназначен для ввода текста пользователем.
  • ListPreference – раскрывающийся список, который содержит массив с ранее созданными параметрами из файла arrays.xml
  • Остальные элементы я описывать не буду, они аналогичны элементам layouts.

Теперь немного о параметрах:

  • app:key – это идентификатор параметра к которому мы будем обращаться из кода.
  • app:defaultValue – значение по умолчанию
  • app:summary – описание элемента
  • app:summaryOn – описание если элемент включен
  • app:summaryOff – описание если элемент выключен
  • app:dependency – указывает от какого элемента зависит этот элемент
  • app:min – минимальное значение элемента
  • app:entries – массив описаний к значениям
  • app:entryValues – массив самих значений

Отредактируем файл MainActivity.kt

Добавим в MainActivity.kt обработчик нажатий кнопки для перехода в меню настроек. Приведенный код вызывает меню, item используя его id. Далее мы создаём намерение действия перехода к SettingsActivity.

// Обработка нажатий кнопок меню
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.setting -> {
                val intent = Intent(this, SettingsActivity::class.java)
                startActivity(intent)
            }
        }
        return super.onOptionsItemSelected(item)
    }

Чтобы добавить в Toolbar экрана настроек кнопку назад, пропишем в файл manifest.xml к SettingsActivity следующую строку:

android:parentActivityName=".MainActivity"

Отредактируем файл SettingActivity.kt

package ru.jandroid.preferencesscreen

import android.content.SharedPreferences
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager

class SettingsActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.settings_activity)

        // Загружаем фрагмент
        if (savedInstanceState == null) {
            supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings, SettingsFragment())
                .commit()
        }

        // Подключаем SharedPreference
        PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this)

    }

    // Соединяем элементы экрана с SharedPreference, чтобы результат писался в память
    class SettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey)
        }
    }

    // Обрабатываем кнопку выбора Темы
    override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
        if (key == "theme"){
            val pref = sharedPreferences?.getString(key,"1")

            when(pref?.toInt()){
                1 ->{
                    AppCompatDelegate.setDefaultNightMode(
                        AppCompatDelegate.MODE_NIGHT_NO)
                }
                2 ->{
                    AppCompatDelegate.setDefaultNightMode(
                        AppCompatDelegate.MODE_NIGHT_YES)
                }
                3 ->{
                    AppCompatDelegate.setDefaultNightMode(
                        AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
                }
            }
        }
    }

    // Отключить SharedPreference, чтобы не занимать память
    override fun onDestroy() {
        super.onDestroy()
        PreferenceManager.getDefaultSharedPreferences(this)
            .unregisterOnSharedPreferenceChangeListener(this)
    }
}

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

class SettingsActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener{

}

Остальные элементы подписаны в коде.

Заключение

Вот так, достаточно просто и быстро можно прописать настройки приложения. Настройки на автомате сохраняются в SharedPreferences. За вами только набросать шаблон экрана настроек и добавить обработку нажатий элементов.

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

Оставьте комментарий

1 × четыре =