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.databinding.InverseBindingListener
|
||||
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.getActivity
|
||||
import com.lukouguoji.module_base.util.Common
|
||||
import com.lxj.xpopup.XPopup
|
||||
import dev.utils.app.info.KeyValue
|
||||
import java.util.Calendar
|
||||
|
||||
@@ -32,7 +30,7 @@ import java.util.Calendar
|
||||
* |-----------|-----------|----------|
|
||||
* | `INPUT` | EditText | 无 |
|
||||
* | `DATE` | TextView(点击弹日历)| 日历 |
|
||||
* | `SPINNER` | Spinner | 下箭头 |
|
||||
* | `SPINNER` | TextView(点击弹底部列表,与 PhoneFormRow SELECT 同款)| 下箭头 |
|
||||
*
|
||||
* XML 用法:
|
||||
* ```xml
|
||||
@@ -58,6 +56,7 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
val llContent: LinearLayout
|
||||
val et: EditText
|
||||
val tv: TextView
|
||||
/** 保留以兼容布局 id;Bug #623 起 SPINNER 形态改为底部弹出列表,原生 Spinner 恒隐藏 */
|
||||
val spinner: Spinner
|
||||
val iv: ImageView
|
||||
|
||||
@@ -85,7 +84,7 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
field = v
|
||||
et.hint = v
|
||||
tv.hint = v
|
||||
bindAdapter(spinner, list, v, R.layout.item_spinner_list_14sp)
|
||||
applyDefaultSelection()
|
||||
}
|
||||
|
||||
var value: String = ""
|
||||
@@ -99,7 +98,7 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
var list: List<KeyValue> = emptyList()
|
||||
set(v) {
|
||||
field = v
|
||||
bindAdapter(spinner, v, hint, R.layout.item_spinner_list_14sp)
|
||||
applyDefaultSelection()
|
||||
applyValue()
|
||||
}
|
||||
|
||||
@@ -114,7 +113,6 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
field = v
|
||||
llContent.isEnabled = v
|
||||
et.isEnabled = v
|
||||
spinner.isEnabled = v
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
when (type) {
|
||||
PhoneDataLayoutType.INPUT -> {
|
||||
@@ -179,12 +192,12 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
|
||||
PhoneDataLayoutType.SPINNER -> {
|
||||
et.visibility = GONE
|
||||
tv.visibility = GONE
|
||||
spinner.visibility = VISIBLE
|
||||
tv.visibility = VISIBLE
|
||||
spinner.visibility = GONE
|
||||
iv.visibility = VISIBLE
|
||||
iv.setImageResource(R.drawable.ic_phone_chevron_down)
|
||||
llContent.setOnClickListener(null)
|
||||
llContent.isClickable = false
|
||||
llContent.setOnClickListener(spinnerClick)
|
||||
applyDefaultSelection()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,10 +213,8 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
PhoneDataLayoutType.SPINNER -> {
|
||||
if (value.isNotEmpty()) {
|
||||
val position = list.indexOfFirst { it.value == value }
|
||||
if (position >= 0) spinner.setSelection(position)
|
||||
}
|
||||
// 显示选中项文案;列表里找不到就按原值显示(如后端返回的历史值),空值显示 hint
|
||||
tv.text = list.firstOrNull { it.value == value }?.key ?: value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,10 +234,10 @@ class PhoneDataLayout @JvmOverloads constructor(
|
||||
|
||||
/** 重置为空值(筛选弹层「重置」按钮使用) */
|
||||
fun reset() {
|
||||
value = ""
|
||||
if (type == PhoneDataLayoutType.SPINNER && list.isNotEmpty()) {
|
||||
spinner.setSelection(if (hint.isEmpty()) list.size - 1 else list.size)
|
||||
}
|
||||
// 与原 Spinner 版本一致:有 hint 回到占位(空值);无 hint 选中最后一项
|
||||
value = if (type == PhoneDataLayoutType.SPINNER && hint.isEmpty() && list.isNotEmpty()) {
|
||||
list.last().value
|
||||
} else ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user