実践AndroidX Preference Library

Androidアプリの開発でAndroidX Preference Libraryを使用して設定画面を構築した際、躓いた点を記載します。

# 前提

Android Studio 3.5.2
Kotlin 1.3
CompileSdkVersion 29

# 準備

アプリケーション配下のbuild.gradleに下記内容を記載し、ライブラリを導入します。

```gradle:build.gradle
implementation 'androidx.preference:preference:1.1.0'
```

# 設定画面の生成

Android StudioのProjectツリーの任意の場所で、コンテキストメニューからNew -> Activity -> Settings Activityを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144437/ce3127d8-b49c-0e5a-2a69-639be640bcc6.png)

選択するとダイアログが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144437/f8579c6a-ba24-6510-9885-fd0893f24f26.png)

Finishで設定画面用のActivityおよび関連ファイル一式を生成します。
生成されるのは

- Activity（内部クラスとしてFragmentを内包。以下、便宜的にSettingsActivityとします）
- Activityのレイアウトファイル
- arrays.xml（リスト選択式の設定項目で使用）
- root_preferences.xml（設定項目を定義）

の4点です。
AndroidManifest等にも必要な定義が追加されます。至れり尽くせり。

# 設定項目を定義する

root_preference.xmlを修正します。
この時点でサンプルとして項目が定義されているので、何となく分かると思います。
使用可能なタグは候補として表示されるので、その中から選べば問題ないです。
app:keyで指定した値がPreferenceのキーとなります。

# 設定画面の呼び出し

通常のActivityと同じです。

```kotlin
startActivity(Intent(applicationContext, SettingsActivity::class.java))
```

# 子画面を作成したい

設定画面に子画面を設けて、一部設定を子画面で行う場合の記述方法です。

## 子画面用の設定項目定義

適当に新規xmlファイルを作成し、root_preference.xmlと同様に項目を定義します。

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

    <PreferenceCategory app:title="子画面">

        <EditTextPreference
            app:key="child"
            app:title="設定1" />

    </PreferenceCategory>

</PreferenceScreen>
```

## 子画面Fragmentの定義

親画面のFragmentと全く同じように定義できます。
ここではサンプル実装に習い、SettingsActivityに内部クラスとして子画面用のFragmentを追加しました。

```kotlin:SettingsActivity.kt
class SettingsActivity : AppCompatActivity() {

    //（中略）

    class SubSettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            setPreferencesFromResource(R.xml.sub_preferences, rootKey)
        }
    }
}
```

## 子画面呼び出し

親画面に子画面へジャンプするための項目を追加します。

```xml:root_preference.xml
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!--（中略）-->

    <Preference
        android:title="子画面"
        app:fragment="com.gmail.lsetzl.preferencesample.SettingsActivity$SubSettingsFragment" />

</PreferenceScreen>
```

# アラートダイアログを表示したい

設定項目タップ時にアラートダイアログを表示する際の記述方法です。
DialogPreference等といったそれっぽいクラスが存在しますが、そちらは使いません。

とりあえず、設定項目を追加します。
app:keyはこの後使用するので必須です。適当なユニーク値を設定しておいてください。

```xml:root_preference.xml
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!--（中略）-->

    <Preference
        app:key="dialog"
        app:title="ダイアログ表示" />

</PreferenceScreen>
```

アラートダイアログの表示元となるFragmentに、onPreferenceTreeClickメソッドのオーバーライドを追加します。
要はタップされた項目を判断して、あとは通常と同じようにダイアログを表示するだけです。

```kotlin:SettingsActivity.kt

    class SettingsFragment : PreferenceFragmentCompat() {
        override fun onPreferenceTreeClick(preference: Preference?): Boolean {
            return when (preference?.key) {
                "dialog" -> {
                    AlertDialog.Builder(context!!)
                        .setTitle("タイトル")
                        .setMessage("メッセージ")
                        .setPositiveButton("OK") { _, _ ->
                            // OKタップ時処理
                        }
                        .show()
                    false
                }
                else -> {
                    true
                }
            }
        }
    }

```

上記コードを含むサンプルコードを下記のリポジトリに置いてあります。
https://github.com/lsetzl/PreferenceSample