简单使用
- values.arrays.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="list_entries">
<item>Option 1</item>
<item>Option 2</item>
<item>Option 3</item>
</string-array>
<string-array name="list_values">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>
- xml.preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:key="simple_preference"
android:summary="This is a simple preference"
android:title="Simple Preference" />
<CheckBoxPreference
android:defaultValue="false"
android:key="checkbox_preference"
android:summary="This is a CheckBox"
android:title="Check Box Preference" />
<EditTextPreference
android:dialogTitle="Enter Text"
android:key="edittext_preference"
android:summary="Enter your text here"
android:title="Edit Text Preference" />
<ListPreference
android:defaultValue="1"
android:entries="@array/list_entries"
android:entryValues="@array/list_values"
android:key="list_preference"
android:summary="Select an option"
android:title="List Preference" />
<com.example.kotlinlearn.Preference.CustomSeekBarPreference
android:defaultValue="50"
android:key="seekbar_preference"
android:title="SeekBar Preference" />
</PreferenceScreen>
- SettingsFragment
package com.example.kotlinlearn.Preference
import android.os.Bundle
import android.util.Log
import androidx.preference.CheckBoxPreference
import androidx.preference.EditTextPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.example.kotlinlearn.R
class SettingsFragment : Preference.OnPreferenceClickListener,
Preference.OnPreferenceChangeListener, PreferenceFragmentCompat() {
var TAG = "SettingsFragment"
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
var findPreference = findPreference<EditTextPreference>("edittext_preference")
findPreference?.onPreferenceClickListener = this
findPreference?.onPreferenceChangeListener = this
}
override fun onPreferenceClick(preference: Preference?): Boolean {
Log.d(TAG, "onPreferenceClick: ")
return false
}
override fun onPreferenceChange(preference: Preference?, newValue: Any?): Boolean {
Log.d(TAG, "onPreferenceChange: ")
return false
}
}
- PreferenceActivity
package com.example.kotlinlearn.Preference
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.kotlinlearn.R
class PreferenceActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_preference)
// Display the fragment as the main content.
supportFragmentManager
.beginTransaction()
.replace(R.id.fragment_container, SettingsFragment())
.commit()
}
}
效果
原理
- 布局:RecyclerView进行布局,PreferenceGroupAdapter,重写onCreateViewHolder()、onBindViewHolder()、getItemCount()
在onCreateViewHolder(ViewGroup parent, int viewType) 中根据viewType判断获取不同的preference。 - Preference:底层调用SharedPreferences进行保存。通过以下方法持久化数值。
persistString,persistStringSet,persistInt,persistFloat,persistLong,persistBoolean
自定义Preference
重点在监听view变化,在变化后通过回调,将终值写入SharedPreferences,在初始化的时候读出值并赋给view。
package com.example.kotlinlearn.Preference
import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import androidx.preference.Preference
import androidx.preference.PreferenceViewHolder
import android.widget.SeekBar
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.kotlinlearn.R
class CustomSeekBarPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) {
private var currentValue: Int = 0
private var maxValue: Int = 100
init {
widgetLayoutResource = R.layout.preference_seekbar
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
val seekBar = holder.findViewById(R.id.seekbar) as SeekBar
val valueText = holder.findViewById(R.id.seekbar_value) as TextView
seekBar.max = maxValue
seekBar.progress = currentValue
valueText.text = currentValue.toString()
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
currentValue = progress
valueText.text = progress.toString()
persistInt(progress)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
}
override fun onGetDefaultValue(a: TypedArray, index: Int): Any {
return a.getInt(index, 0)
}
override fun onSetInitialValue(defaultValue: Any?) {
currentValue = getPersistedInt(defaultValue as? Int ?: 0)
}
}
ex:
1.当xml中设置组件的id相同时,会导致多个preference的值相同。