feat(form): 添加动态表单组件和下拉选择功能
- 新增 FormField 数据模型定义五种字段类型(文本、数字、下拉、日期、固定值) - 实现 FormFieldAdapter 适配器支持动态表单渲染和数据绑定 - 添加 DropdownPopup 弹窗组件和 DropdownAdapter 适配器 - 新增多个圆角背景资源文件(bg_gray_radius10、bg_white_radius10_stroke 等) - 在 Common.kt 中添加 hideKeyboard 扩展函数用于隐藏软键盘 - 创建 DictType 数据模型用于字典类型数据传输 - 添加表单项和下拉项的布局文件(list_item_form_field、list_item_dropdown 等)
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package com.shuwei.dish.match.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.shuwei.dish.match.databinding.ListItemDropdownBinding
|
||||
import com.shuwei.dish.match.model.DictType
|
||||
import com.shuwei.dish.match.utils.ext.gone
|
||||
import com.shuwei.dish.match.utils.ext.visible
|
||||
|
||||
class DropdownAdapter(var list: MutableList<DictType>) :
|
||||
BaseQuickAdapter<DictType, DropdownAdapter.VH>(list) {
|
||||
|
||||
inner class VH(var binding: ListItemDropdownBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val binding = ListItemDropdownBinding.inflate(inflater, parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: DictType?) {
|
||||
holder.binding.tvDropdown.text = item?.value
|
||||
holder.binding.divider.run {
|
||||
if (position == list.size - 1) gone() else visible()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package com.shuwei.dish.match.adapter
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.content.Context
|
||||
import android.text.Editable
|
||||
import android.text.InputType
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.TextWatcher
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.toColorInt
|
||||
import com.chad.library.adapter4.BaseQuickAdapter
|
||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||
import com.shuwei.dish.match.R
|
||||
import com.shuwei.dish.match.databinding.ListItemFormFieldBinding
|
||||
import com.shuwei.dish.match.dialog.DropdownPopup
|
||||
import com.shuwei.dish.match.model.FieldType
|
||||
import com.shuwei.dish.match.model.FormField
|
||||
import com.shuwei.dish.match.utils.ext.dp
|
||||
import com.shuwei.dish.match.utils.ext.gone
|
||||
import com.shuwei.dish.match.utils.ext.hideKeyboard
|
||||
import com.shuwei.dish.match.utils.ext.visible
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* 动态表单字段 Adapter,配合 FlexboxLayoutManager 实现两列自动换行布局
|
||||
* 单一 item 布局,通过 visibility 控制 TEXT/NUMBER/FIXED/DROPDOWN/DATE_PICKER 五种类型渲染
|
||||
*
|
||||
* @param activityContext Activity context,用于创建 DatePickerDialog
|
||||
* @param fields 表单字段列表(hidden=false 的字段,由外部过滤后传入)
|
||||
*/
|
||||
class FormFieldAdapter(
|
||||
private val activityContext: Context,
|
||||
fields: MutableList<FormField>
|
||||
) : BaseQuickAdapter<FormField, FormFieldAdapter.VH>(fields) {
|
||||
|
||||
private val isoFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
|
||||
private val displayDateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
|
||||
inner class VH(val binding: ListItemFormFieldBinding) : QuickViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
||||
val binding = ListItemFormFieldBinding.inflate(LayoutInflater.from(context), parent, false)
|
||||
return VH(binding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int, item: FormField?) {
|
||||
item ?: return
|
||||
val b = holder.binding
|
||||
|
||||
// 设置标签,必填项追加红色星号
|
||||
b.tvLabel.text = buildLabelSpannable(item.label, item.required)
|
||||
|
||||
// 先全部隐藏,再按类型显示对应控件
|
||||
b.etInput.gone()
|
||||
b.flDropdown.gone()
|
||||
b.flDatePicker.gone()
|
||||
|
||||
// 移除旧的 TextWatcher,防止 RecyclerView 复用时错误触发
|
||||
(b.etInput.tag as? TextWatcher)?.let { b.etInput.removeTextChangedListener(it) }
|
||||
b.etInput.tag = null
|
||||
|
||||
when (item.type) {
|
||||
FieldType.TEXT -> bindEditText(b, item, InputType.TYPE_CLASS_TEXT)
|
||||
FieldType.NUMBER -> bindEditText(
|
||||
b, item,
|
||||
InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL or InputType.TYPE_NUMBER_FLAG_SIGNED
|
||||
)
|
||||
FieldType.FIXED -> bindFixed(b, item)
|
||||
FieldType.DROPDOWN -> bindDropdown(b, item)
|
||||
FieldType.DATE_PICKER -> bindDatePicker(b, item)
|
||||
}
|
||||
}
|
||||
|
||||
/** 绑定可编辑文本框(TEXT / NUMBER) */
|
||||
private fun bindEditText(b: ListItemFormFieldBinding, item: FormField, inputType: Int) {
|
||||
b.etInput.visible()
|
||||
b.etInput.isEnabled = true
|
||||
b.etInput.inputType = inputType
|
||||
b.etInput.hint = item.hint.ifBlank { item.label }
|
||||
b.etInput.setBackgroundResource(R.drawable.bg_white_radius10_stroke2)
|
||||
b.etInput.setText(item.value)
|
||||
b.etInput.setSelection(b.etInput.text.length)
|
||||
|
||||
val watcher = object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
item.value = s?.toString() ?: ""
|
||||
}
|
||||
}
|
||||
b.etInput.addTextChangedListener(watcher)
|
||||
b.etInput.tag = watcher
|
||||
}
|
||||
|
||||
/** 绑定固定值(不可编辑,灰色背景区分) */
|
||||
private fun bindFixed(b: ListItemFormFieldBinding, item: FormField) {
|
||||
b.etInput.visible()
|
||||
b.etInput.isEnabled = false
|
||||
b.etInput.inputType = InputType.TYPE_CLASS_TEXT
|
||||
b.etInput.hint = ""
|
||||
b.etInput.setBackgroundResource(R.drawable.bg_gray_radius10)
|
||||
b.etInput.setText(item.value)
|
||||
}
|
||||
|
||||
/** 绑定下拉选择框,点击时创建 DropdownPopup */
|
||||
private fun bindDropdown(b: ListItemFormFieldBinding, item: FormField) {
|
||||
b.flDropdown.visible()
|
||||
b.tvDropdownValue.hint = item.hint.ifBlank { "请选择${item.label}" }
|
||||
b.tvDropdownValue.text = item.value.ifBlank { null }
|
||||
|
||||
b.flDropdown.setOnClickListener { v ->
|
||||
v.hideKeyboard()
|
||||
val popHeight = min(item.options.size.coerceAtLeast(1), 4) * 71.dp
|
||||
DropdownPopup(
|
||||
context = activityContext,
|
||||
list = item.options.toMutableList(),
|
||||
popWidth = v.width,
|
||||
popHeight = popHeight
|
||||
) { dictType ->
|
||||
item.value = dictType.value ?: ""
|
||||
item.valueId = dictType.id ?: ""
|
||||
b.tvDropdownValue.text = item.value
|
||||
// 将 extraApiKeys 映射的 DictType 字段值写入 extraValues
|
||||
item.extraValues.clear()
|
||||
item.extraApiKeys.forEach { (apiKey, dictField) ->
|
||||
val fieldValue = when (dictField) {
|
||||
"id" -> dictType.id ?: ""
|
||||
"value" -> dictType.value ?: ""
|
||||
"type" -> dictType.type
|
||||
else -> ""
|
||||
}
|
||||
item.extraValues[apiKey] = fieldValue
|
||||
}
|
||||
}.also {
|
||||
it.bgLayout = b.flDropdown
|
||||
it.showAsDropDown(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 绑定日期选择器,点击时弹出 DatePickerDialog */
|
||||
private fun bindDatePicker(b: ListItemFormFieldBinding, item: FormField) {
|
||||
b.flDatePicker.visible()
|
||||
b.tvDateValue.hint = item.hint.ifBlank { "请选择日期" }
|
||||
b.tvDateValue.text = item.value.ifBlank { null }
|
||||
|
||||
b.flDatePicker.setOnClickListener { v ->
|
||||
v.hideKeyboard()
|
||||
val cal = Calendar.getInstance()
|
||||
DatePickerDialog(
|
||||
activityContext,
|
||||
{ _, year, month, dayOfMonth ->
|
||||
val selected = Calendar.getInstance().apply {
|
||||
set(year, month, dayOfMonth, 0, 0, 0)
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
}
|
||||
// value 存显示格式,valueId 存 ISO 格式供提交使用
|
||||
item.value = displayDateFormat.format(selected.time)
|
||||
item.valueId = isoFormat.format(selected.time)
|
||||
b.tvDateValue.text = item.value
|
||||
},
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
/** 构建带红色星号的必填标签 */
|
||||
private fun buildLabelSpannable(label: String, required: Boolean): SpannableStringBuilder {
|
||||
return SpannableStringBuilder().apply {
|
||||
append(label)
|
||||
if (required) {
|
||||
val start = length
|
||||
append(" *")
|
||||
setSpan(
|
||||
ForegroundColorSpan("#FFCC0000".toColorInt()),
|
||||
start, length,
|
||||
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.shuwei.dish.match.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.PopupWindow
|
||||
import androidx.core.graphics.drawable.toDrawable
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.shuwei.dish.match.R
|
||||
import com.shuwei.dish.match.adapter.DropdownAdapter
|
||||
import com.shuwei.dish.match.databinding.LayoutPopupDropdownBinding
|
||||
import com.shuwei.dish.match.model.DictType
|
||||
import com.shuwei.dish.match.utils.ext.dp
|
||||
|
||||
class DropdownPopup(
|
||||
var context: Context,
|
||||
var list: MutableList<DictType>,
|
||||
var popWidth: Int = 280.dp,
|
||||
var popHeight: Int = 284.dp,
|
||||
var onPopupItemClick: (DictType) -> Unit
|
||||
) : PopupWindow() {
|
||||
|
||||
init {
|
||||
// 初始化PopupWindow
|
||||
// val popupView = LayoutInflater.from(context).inflate(R.layout.layout_popup_dropdown, null)
|
||||
val binding = LayoutPopupDropdownBinding.inflate(LayoutInflater.from(context))
|
||||
contentView = binding.root
|
||||
width = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
height = ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
// 设置透明背景,避免覆盖圆角
|
||||
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
|
||||
isOutsideTouchable = true
|
||||
isFocusable = true
|
||||
|
||||
// 设置动画样式
|
||||
// animationStyle = R.style.PopupAnimation
|
||||
|
||||
// 初始化视图和事件
|
||||
initViews(binding.rvWarehouse)
|
||||
}
|
||||
|
||||
private fun initViews(rv: RecyclerView) {
|
||||
// 获取关闭按钮并设置点击事件
|
||||
rv.updateLayoutParams {
|
||||
width = popWidth
|
||||
height = popHeight
|
||||
}
|
||||
rv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
rv.adapter = DropdownAdapter(list).setOnItemClickListener { adapter, view, position ->
|
||||
onPopupItemClick(list[position])
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
var arrowImage: ImageView? = null
|
||||
|
||||
var bgLayout: ViewGroup? = null
|
||||
|
||||
var defLayoutBgResId = R.drawable.bg_white_radius10_stroke2
|
||||
|
||||
override fun showAsDropDown(anchor: View?) {
|
||||
super.showAsDropDown(anchor)
|
||||
bgLayout?.setBackgroundResource(R.drawable.bg_white_stroke_blue)
|
||||
arrowImage?.setImageResource(R.mipmap.ic_triangle_up)
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
bgLayout?.setBackgroundResource(defLayoutBgResId)
|
||||
arrowImage?.setImageResource(R.mipmap.ic_triangle_down)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.shuwei.dish.match.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* 字典类型 如仓库列表 物品类型 存储方式等
|
||||
*/
|
||||
@Parcelize
|
||||
data class DictType(
|
||||
val id: String? = null,
|
||||
val value: String? = null,
|
||||
val type: String = ""
|
||||
) : Parcelable
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.shuwei.dish.match.model
|
||||
|
||||
/** 表单字段类型枚举 */
|
||||
enum class FieldType {
|
||||
/** 普通文本输入 */
|
||||
TEXT,
|
||||
/** 数字输入(支持小数和负数) */
|
||||
NUMBER,
|
||||
/** 下拉选择 */
|
||||
DROPDOWN,
|
||||
/** 日期选择弹窗 */
|
||||
DATE_PICKER,
|
||||
/** 固定值,不可编辑 */
|
||||
FIXED
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态表单字段数据模型
|
||||
* @param label 字段标签名称
|
||||
* @param type 字段类型,决定渲染哪种输入控件
|
||||
* @param apiKey 非下拉字段对应的接口参数名,空字符串表示不提交
|
||||
* @param extraApiKeys 下拉字段的多接口参数映射,key=接口参数名,value=DictType 字段名(id/value/type)
|
||||
* @param required 是否必填,提交时校验
|
||||
* @param hidden 是否隐藏,hidden=true 时不渲染该字段
|
||||
* @param hint 校验失败提示文案,同时作为输入框 hint
|
||||
* @param options 下拉框选项列表(DROPDOWN 类型使用)
|
||||
* @param submitValueId 提交时使用 valueId 而非 value;DATE_PICKER 选 ISO 格式时设为 true
|
||||
* @param value 当前显示值/输入值;DATE_PICKER 存 yyyy-MM-dd 显示格式
|
||||
* @param valueId DATE_PICKER 存 ISO 格式 yyyy-MM-dd'T'HH:mm:ss
|
||||
* @param extraValues 下拉选中后按 extraApiKeys 映射存储的提交值,key=接口参数名
|
||||
*/
|
||||
data class FormField(
|
||||
val label: String,
|
||||
val type: FieldType,
|
||||
val apiKey: String = "",
|
||||
val extraApiKeys: Map<String, String> = emptyMap(),
|
||||
val required: Boolean = false,
|
||||
val hidden: Boolean = false,
|
||||
val hint: String = "",
|
||||
val options: List<DictType> = emptyList(),
|
||||
val submitValueId: Boolean = false,
|
||||
var value: String = "",
|
||||
var valueId: String = "",
|
||||
val extraValues: MutableMap<String, String> = mutableMapOf()
|
||||
)
|
||||
@@ -10,6 +10,7 @@ import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageView
|
||||
import android.widget.Toast
|
||||
@@ -160,4 +161,10 @@ fun Double.roundedOneDecimalPlace(): Double {
|
||||
}
|
||||
fun ImageView.load(url: Any?) {
|
||||
GlideUtils.loadImage(context, url, this)
|
||||
}
|
||||
|
||||
fun View.hideKeyboard() {
|
||||
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(this.windowToken, 0)
|
||||
this.clearFocus() // 清除焦点避免键盘再次弹出
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFDCDCF0"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<corners android:radius="10dp"/>
|
||||
<stroke android:color="#FFD5E1FF" android:width="2dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white"/>
|
||||
<corners android:radius="10dp"/>
|
||||
<stroke android:color="#FFDCDCF0" android:width="2dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="@color/white"/>
|
||||
<stroke android:color="#FF0032C8" android:width="2dp"/>
|
||||
<corners android:radius="10dp"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvWarehouse"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:itemCount="10"
|
||||
android:layout_margin="1dp"
|
||||
android:overScrollMode="never"
|
||||
tools:listitem="@layout/list_item_dropdown"
|
||||
android:background="@drawable/bg_white_radius10_stroke" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/ripple_effect_light">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDropdown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="70dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#ff000033"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="选择仓库" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#90D5E1FF" />
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingVertical="10dp">
|
||||
|
||||
<!-- 字段标签,必填项红色星号由 Adapter 通过 SpannableString 追加 -->
|
||||
<TextView
|
||||
android:id="@+id/tvLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:textColor="#FF141428"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="食材名称" />
|
||||
|
||||
<!-- 输入区域容器,三种控件叠放,按 FieldType 切换 visibility -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginHorizontal="12dp">
|
||||
|
||||
<!-- TEXT / NUMBER / FIXED 类型:EditText -->
|
||||
<EditText
|
||||
android:id="@+id/etInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:focusableInTouchMode="true"
|
||||
android:maxLines="1"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:textColor="#FF141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
android:visibility="gone"
|
||||
tools:ignore="Autofill,TextFields" />
|
||||
|
||||
<!-- DROPDOWN 类型:点击触发 DropdownPopup -->
|
||||
<FrameLayout
|
||||
android:id="@+id/flDropdown"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDropdownValue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="44dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="#FF141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
<!-- DATE_PICKER 类型:点击触发 DatePickerDialog -->
|
||||
<FrameLayout
|
||||
android:id="@+id/flDatePicker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_white_radius10_stroke2"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDateValue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="44dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#FF141428"
|
||||
android:textColorHint="#FF96A0AA"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@mipmap/ic_triangle_down"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 763 B |
Binary file not shown.
|
After Width: | Height: | Size: 689 B |
Reference in New Issue
Block a user