LoginSignup
9
13

More than 5 years have passed since last update.

【Android】動的にPreferenceを追加したり、項目を変更する

Last updated at Posted at 2017-04-11

tl;dr

xmlでPreferenceを定義すると、リストの項目とかをあらかじめ定義しないといけなくなります。
DBからリストの値を取ってきたいとか、動的にリストの項目を変える方法の備忘録。

Preferenceを新規追加するとき

AddPreferenceFragment.kt
    class AddPreferenceFragment : PreferenceFragment() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            addPreferencesFromResource(R.xml.add_pref)
            val programmableEntries = arrayOf("サル", "ゴリラ", "チンパンジー")
            preferenceScreen.addPreference(ListPreference(this.activity).apply {
                title = "追加されたヤツ"
                key = "key_added_pref"
                dialogTitle = "ダイアログのタイトル"
                setDefaultValue("最初から設定されてるヤツ")
                entries = programmableEntries
                entryValues = programmableEntries
            })
       }

preferenceScreenを取得した後に、addPrefenreceするだけです。
リストの項目をentriesとentryValuesでセットします。

xmlで記述するときは
titleを設定するとダイアログにも同じタイトルが出るのですが、
コード上でpreferenceを作る場合は、dialogTitleを設定してやらないと出ないようです。

既存のPreferenceの値を変えるとき

ReplacePreferenceFragment.kt
    class ReplacePreferenceFragment : PreferenceFragment() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            addPreferencesFromResource(R.xml.add_pref)
            val programmableEntries = arrayOf("サル", "ゴリラ", "チンパンジー")
            findPreference(getString(R.string.key_pref_replace)) as? SelectListPreference)?.apply {
                entries = programmableEntries
                entryValues = programmableEntries
            }) 
        }

こちらはfindPreferenceでxmlに予め設定してあるkeyからpreferenceを取得します。
findPreferenceはfindViewByIdと同じようにPreferenceの基底クラスで返されるので、キャストしてあげる。
あとは同じようにentriesとentryValuesでセットするだけ。

ポイントとか

最初にaddPreferenceFromResourceを呼ぶ

最初にどのxmlからPreferenceを取得しているかを知る必要があるので、
preferenceScreenやfindPrefenreceを呼ぶ前に
addPreferenceFromResourceを呼んでください。

MultiListPreferenceを使う場合

defaultValueを設定する場合は、Array型ではなく、Set型にする必要があるのでお忘れなく。

addPrefenreceのPrefereceに渡すContextはactivityで

この記事のコードもPreferenceを追加するときに
preferenceScreen.addPreference(ListPreference(this.activity)
とactivityを渡してますが、これにApplicationContextとかBaseContextとか渡しても、
これらのContextは画面に関する情報を持ってないのでDialogの生成ができずに、

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

とかで落ちます。

9
13
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
9
13