fix(phone): PhoneDataLayout 下拉改为底部弹出列表
筛选面板与弹框里的 PhoneDataLayout 原用系统 Spinner,点开是贴在输入框下的下拉菜单。 SPINNER 形态改为与 PhoneFormRow 同款 XPopup 底部列表(标题取 hint),保留原取值语义: 无 hint 默认选中第一项、有 hint 为空值,筛选「重置」逻辑不变。19 个手机布局随之生效。 Refs: 禅道 Bug #623 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,12 +13,10 @@ import android.widget.TextView
|
|||||||
import androidx.core.widget.doOnTextChanged
|
import androidx.core.widget.doOnTextChanged
|
||||||
import androidx.databinding.InverseBindingListener
|
import androidx.databinding.InverseBindingListener
|
||||||
import com.lukouguoji.module_base.R
|
import com.lukouguoji.module_base.R
|
||||||
import com.lukouguoji.module_base.adapter.bindAdapter
|
|
||||||
import com.lukouguoji.module_base.adapter.bindOnSelected
|
|
||||||
import com.lukouguoji.module_base.interfaces.IOnSpinnerSelected
|
|
||||||
import com.lukouguoji.module_base.ktx.formatDate
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
import com.lukouguoji.module_base.ktx.getActivity
|
import com.lukouguoji.module_base.ktx.getActivity
|
||||||
import com.lukouguoji.module_base.util.Common
|
import com.lukouguoji.module_base.util.Common
|
||||||
|
import com.lxj.xpopup.XPopup
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
|
||||||
@@ -32,7 +30,7 @@ import java.util.Calendar
|
|||||||
* |-----------|-----------|----------|
|
* |-----------|-----------|----------|
|
||||||
* | `INPUT` | EditText | 无 |
|
* | `INPUT` | EditText | 无 |
|
||||||
* | `DATE` | TextView(点击弹日历)| 日历 |
|
* | `DATE` | TextView(点击弹日历)| 日历 |
|
||||||
* | `SPINNER` | Spinner | 下箭头 |
|
* | `SPINNER` | TextView(点击弹底部列表,与 PhoneFormRow SELECT 同款)| 下箭头 |
|
||||||
*
|
*
|
||||||
* XML 用法:
|
* XML 用法:
|
||||||
* ```xml
|
* ```xml
|
||||||
@@ -58,6 +56,7 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
val llContent: LinearLayout
|
val llContent: LinearLayout
|
||||||
val et: EditText
|
val et: EditText
|
||||||
val tv: TextView
|
val tv: TextView
|
||||||
|
/** 保留以兼容布局 id;Bug #623 起 SPINNER 形态改为底部弹出列表,原生 Spinner 恒隐藏 */
|
||||||
val spinner: Spinner
|
val spinner: Spinner
|
||||||
val iv: ImageView
|
val iv: ImageView
|
||||||
|
|
||||||
@@ -85,7 +84,7 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
field = v
|
field = v
|
||||||
et.hint = v
|
et.hint = v
|
||||||
tv.hint = v
|
tv.hint = v
|
||||||
bindAdapter(spinner, list, v, R.layout.item_spinner_list_14sp)
|
applyDefaultSelection()
|
||||||
}
|
}
|
||||||
|
|
||||||
var value: String = ""
|
var value: String = ""
|
||||||
@@ -99,7 +98,7 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
var list: List<KeyValue> = emptyList()
|
var list: List<KeyValue> = emptyList()
|
||||||
set(v) {
|
set(v) {
|
||||||
field = v
|
field = v
|
||||||
bindAdapter(spinner, v, hint, R.layout.item_spinner_list_14sp)
|
applyDefaultSelection()
|
||||||
applyValue()
|
applyValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +113,6 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
field = v
|
field = v
|
||||||
llContent.isEnabled = v
|
llContent.isEnabled = v
|
||||||
et.isEnabled = v
|
et.isEnabled = v
|
||||||
spinner.isEnabled = v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -136,13 +134,6 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindOnSelected(spinner, object : IOnSpinnerSelected {
|
|
||||||
override fun onSelected(position: Int) {
|
|
||||||
value = list.getOrNull(position)?.value ?: ""
|
|
||||||
refreshCallBack?.invoke()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
applyType()
|
applyType()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +148,28 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** SPINNER:底部弹出列表(标题取 hint,无 hint 时取 title),选中后回写 value 并回调 */
|
||||||
|
private val spinnerClick: (v: View) -> Unit = {
|
||||||
|
if (enable && list.isNotEmpty()) {
|
||||||
|
XPopup.Builder(context)
|
||||||
|
.asBottomList(hint.ifEmpty { title }, list.map { it.key }.toTypedArray()) { position, _ ->
|
||||||
|
value = list.getOrNull(position)?.value ?: ""
|
||||||
|
refreshCallBack?.invoke()
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保持原生 Spinner 的默认取值语义:无 hint 时自动选中第一项(value 为空才补),
|
||||||
|
* 有 hint 时保持空值显示占位文字。
|
||||||
|
*/
|
||||||
|
private fun applyDefaultSelection() {
|
||||||
|
if (type == PhoneDataLayoutType.SPINNER && hint.isEmpty() && value.isEmpty() && list.isNotEmpty()) {
|
||||||
|
value = list[0].value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun applyType() {
|
private fun applyType() {
|
||||||
when (type) {
|
when (type) {
|
||||||
PhoneDataLayoutType.INPUT -> {
|
PhoneDataLayoutType.INPUT -> {
|
||||||
@@ -179,12 +192,12 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
|
|
||||||
PhoneDataLayoutType.SPINNER -> {
|
PhoneDataLayoutType.SPINNER -> {
|
||||||
et.visibility = GONE
|
et.visibility = GONE
|
||||||
tv.visibility = GONE
|
tv.visibility = VISIBLE
|
||||||
spinner.visibility = VISIBLE
|
spinner.visibility = GONE
|
||||||
iv.visibility = VISIBLE
|
iv.visibility = VISIBLE
|
||||||
iv.setImageResource(R.drawable.ic_phone_chevron_down)
|
iv.setImageResource(R.drawable.ic_phone_chevron_down)
|
||||||
llContent.setOnClickListener(null)
|
llContent.setOnClickListener(spinnerClick)
|
||||||
llContent.isClickable = false
|
applyDefaultSelection()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,10 +213,8 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
PhoneDataLayoutType.SPINNER -> {
|
PhoneDataLayoutType.SPINNER -> {
|
||||||
if (value.isNotEmpty()) {
|
// 显示选中项文案;列表里找不到就按原值显示(如后端返回的历史值),空值显示 hint
|
||||||
val position = list.indexOfFirst { it.value == value }
|
tv.text = list.firstOrNull { it.value == value }?.key ?: value
|
||||||
if (position >= 0) spinner.setSelection(position)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,10 +234,10 @@ class PhoneDataLayout @JvmOverloads constructor(
|
|||||||
|
|
||||||
/** 重置为空值(筛选弹层「重置」按钮使用) */
|
/** 重置为空值(筛选弹层「重置」按钮使用) */
|
||||||
fun reset() {
|
fun reset() {
|
||||||
value = ""
|
// 与原 Spinner 版本一致:有 hint 回到占位(空值);无 hint 选中最后一项
|
||||||
if (type == PhoneDataLayoutType.SPINNER && list.isNotEmpty()) {
|
value = if (type == PhoneDataLayoutType.SPINNER && hint.isEmpty() && list.isNotEmpty()) {
|
||||||
spinner.setSelection(if (hint.isEmpty()) list.size - 1 else list.size)
|
list.last().value
|
||||||
}
|
} else ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user