LoginSignup
17
22

More than 5 years have passed since last update.

【Android】便利なPreferenceFragmentCompatで設定画面を作る

Posted at

Jetpack Preference

公式ページ

JetpackのPreferenceを使う事で、設定画面を簡単に作成する事ができる。

:computer:環境構築


app/build.gradle に以下を追加

dependencies {
    implementation 'androidx.preference:preference:1.0.0'
}

:pencil: 実装


簡単なサンプル

  1. まずは設定の項目を定義した、res/xml/preferences.xml を以下の内容で作成する

    <androidx.preference.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"/>
    
    </androidx.preference.PreferenceScreen>
    

    ※ xmlのルートが PreferenceScreen になっている事に注意

  2. 次に PreferenceFragmentCompat を継承したFragmentを作成

    SettingsFragment.kt
    class SettingsFragment : PreferenceFragmentCompat() {
    
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.preferences, rootKey)
        }
    }
    

    setPreferencesFromResource で定義した res/xml/preferences.xml を設定

  3. 土台となるActivityで作成した SettingsFragment を表示する

    SettingsActivity.kt
    class SettingsActivity : RxAppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_settings)
    
            supportFragmentManager
                .beginTransaction()
                .replace(R.id.settingsContainer, SettingsFragment())
                .commit()
        }
    }
    

    レイアウトファイルにはFragmentが表示される FrameLayout を定義

    res/layout/activity_settings.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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">
    
        <androidx.appcompat.widget.Toolbar
                android:id="@+id/settingsToolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:minHeight="?attr/actionBarSize"
                android:background="?attr/colorPrimaryDark"
                app:titleTextColor="@android:color/white"/>
    
        <FrameLayout
                android:id="@+id/settingsContainer"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/settingsToolbar"/>
    
    </RelativeLayout>
    

上記まで実装したら、一度実行してみる。
image.png (40.2 kB)

res/xml/preferences.xml で定義した内容が表示されていればOK

SharedPreferenceファイル名

作成されるSharedPreferenceファイル名は

"${BuildConfig.APPLICATION_ID}_preferences"

となる。

Preferenceの種類

一覧はこちら

  • Preference
    • 基本的な構成要素で対応するキーと値のペアを持つ
  • EditTextPreference
    • String値を保持するPreference、入力欄がテキストフィールドで表示される
  • ListPreference
    • String値を保持するPreference、入力欄がラジオボタンのリストで表示される
  • MultiSelectListPreference
    • 一連の文字列を永続化する設定、入力欄がラベル付きチェックボックスのリストで表示される
  • SeekBarPreference
    • 整数値を保持する設定、入力欄がシークバーで表示される
  • SwitchPreferenceCompat
    • ブール値を保持する設定、入力欄がスイッチで表示される
  • CheckBoxPreference
    • ブール値を保持する設定、入力欄がチェックボックスで表示される

:raised_hands: SharedPreferencesに保存された時に何かしたい場合


SharedPreferences.OnSharedPreferenceChangeListenerを使う

SharedPreferences#registerOnSharedPreferenceChangeListener でlistenerを登録。
※ 上記を無名関数でやっちゃうと上手く動かないので注意 こちら参照

PreferenceFragmentCompatが終了するタイミングで登録解除する
SharedPreferences#unregisterOnSharedPreferenceChangeListener

    var sharedPreferences: SharedPreferences? = null

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)

        context?.also {
            // SharedPreferencesを取得しOnSharedPreferenceChangeListenerを設定
            sharedPreferences = it.getSharedPreferences("xxxxxxxxx", Context.MODE_PRIVATE).apply {
                registerOnSharedPreferenceChangeListener(changeListener)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        context?.also {
            // OnSharedPreferenceChangeListenerの登録解除
     sharedPreferences?.unregisterOnSharedPreferenceChangeListener(changeListener)
        }
    }

    private val changeListener = SharedPreferences.OnSharedPreferenceChangeListener { pref, key ->
        // do something
    }

:link: 関連リンク


17
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
22