Clean up SpinnerPreference a bit

This commit is contained in:
arkon 2021-03-28 16:13:59 -04:00
parent 437c995d12
commit dfa07a5f35

View file

@ -16,8 +16,6 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
FrameLayout(context, attrs) { FrameLayout(context, attrs) {
private var entries = emptyList<String>() private var entries = emptyList<String>()
private var selectedPosition = 0
private var pref: Preference<Int>? = null
private var prefOffset = 0 private var prefOffset = 0
private var popup: PopupMenu? = null private var popup: PopupMenu? = null
@ -38,28 +36,26 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
init { init {
addView(binding.root) addView(binding.root)
val a = context.obtainStyledAttributes(attrs, R.styleable.SpinnerPreference, 0, 0) val attr = context.obtainStyledAttributes(attrs, R.styleable.SpinnerPreference)
val str = a.getString(R.styleable.SpinnerPreference_title) ?: "" val title = attr.getString(R.styleable.SpinnerPreference_title).orEmpty()
binding.title.text = str binding.title.text = title
val entries = (a.getTextArray(R.styleable.SpinnerPreference_android_entries) ?: emptyArray()).map { it.toString() } val entries = (attr.getTextArray(R.styleable.SpinnerPreference_android_entries) ?: emptyArray()).map { it.toString() }
this.entries = entries this.entries = entries
binding.details.text = entries.firstOrNull().orEmpty() binding.details.text = entries.firstOrNull().orEmpty()
a.recycle() attr.recycle()
} }
fun setSelection(selection: Int) { fun setSelection(selection: Int) {
selectedPosition = selection
binding.details.text = entries.getOrNull(selection).orEmpty() binding.details.text = entries.getOrNull(selection).orEmpty()
} }
fun bindToPreference(pref: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null) { fun bindToPreference(pref: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null) {
setSelection(pref.get() - offset) setSelection(pref.get() - offset)
this.pref = pref
prefOffset = offset prefOffset = offset
popup = makeSettingsPopup(pref, prefOffset, block) popup = makeSettingsPopup(pref, prefOffset, block)
setOnTouchListener(popup?.dragToOpenListener) setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener { setOnClickListener {
@ -70,6 +66,7 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
inline fun <reified T : Enum<T>> bindToPreference(pref: Preference<T>) { inline fun <reified T : Enum<T>> bindToPreference(pref: Preference<T>) {
val enumConstants = T::class.java.enumConstants val enumConstants = T::class.java.enumConstants
enumConstants?.indexOf(pref.get())?.let { setSelection(it) } enumConstants?.indexOf(pref.get())?.let { setSelection(it) }
val popup = makeSettingsPopup(pref) val popup = makeSettingsPopup(pref)
setOnTouchListener(popup.dragToOpenListener) setOnTouchListener(popup.dragToOpenListener)
setOnClickListener { setOnClickListener {
@ -79,9 +76,9 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
fun bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int, block: ((Int) -> Unit)? = null) { fun bindToIntPreference(pref: Preference<Int>, @ArrayRes intValuesResource: Int, block: ((Int) -> Unit)? = null) {
setSelection(pref.get()) setSelection(pref.get())
this.pref = pref
prefOffset = 0 prefOffset = 0
val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() } val intValues = resources.getStringArray(intValuesResource).map { it.toIntOrNull() }
popup = makeSettingsPopup(pref, intValues, block) popup = makeSettingsPopup(pref, intValues, block)
setOnTouchListener(popup?.dragToOpenListener) setOnTouchListener(popup?.dragToOpenListener)
setOnClickListener { setOnClickListener {
@ -90,71 +87,50 @@ class SpinnerPreference @JvmOverloads constructor(context: Context, attrs: Attri
} }
inline fun <reified T : Enum<T>> makeSettingsPopup(preference: Preference<T>): PopupMenu { inline fun <reified T : Enum<T>> makeSettingsPopup(preference: Preference<T>): PopupMenu {
val popup = popup() return createPopupMenu { pos ->
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
onItemSelectedListener?.invoke(pos) onItemSelectedListener?.invoke(pos)
true
}
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val enumConstants = T::class.java.enumConstants val enumConstants = T::class.java.enumConstants
val pos = menuClicked(menuItem) enumConstants?.get(pos)?.let { enumValue -> preference.set(enumValue) }
enumConstants?.get(pos)?.let { preference.set(it) }
true
} }
return popup
} }
private fun makeSettingsPopup(preference: Preference<Int>, intValues: List<Int?>, block: ((Int) -> Unit)? = null): PopupMenu { private fun makeSettingsPopup(preference: Preference<Int>, intValues: List<Int?>, block: ((Int) -> Unit)? = null): PopupMenu {
val popup = popup() return createPopupMenu { pos ->
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
preference.set(intValues[pos] ?: 0) preference.set(intValues[pos] ?: 0)
block?.invoke(pos) block?.invoke(pos)
true
} }
return popup
} }
private fun makeSettingsPopup(preference: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null): PopupMenu { private fun makeSettingsPopup(preference: Preference<Int>, offset: Int = 0, block: ((Int) -> Unit)? = null): PopupMenu {
val popup = popup() return createPopupMenu { pos ->
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
preference.set(pos + offset) preference.set(pos + offset)
block?.invoke(pos) block?.invoke(pos)
true
} }
return popup
} }
private fun makeSettingsPopup(): PopupMenu { private fun makeSettingsPopup(): PopupMenu {
val popup = popup() return createPopupMenu { pos ->
// Set a listener so we are notified if a menu item is clicked
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
onItemSelectedListener?.invoke(pos) onItemSelectedListener?.invoke(pos)
true
} }
return popup
} }
fun menuClicked(menuItem: MenuItem): Int { private fun menuClicked(menuItem: MenuItem): Int {
val pos = menuItem.itemId val pos = menuItem.itemId
setSelection(pos) setSelection(pos)
return pos return pos
} }
fun popup(): PopupMenu { fun createPopupMenu(onItemClick: (Int) -> Unit): PopupMenu {
val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0) val popup = PopupMenu(context, this, Gravity.END, R.attr.actionOverflowMenuStyle, 0)
entries.forEachIndexed { index, entry -> entries.forEachIndexed { index, entry ->
popup.menu.add(0, index, 0, entry) popup.menu.add(0, index, 0, entry)
} }
popup.setOnMenuItemClickListener { menuItem ->
val pos = menuClicked(menuItem)
onItemClick(pos)
true
}
return popup return popup
} }
} }