现在数值选择可以直接输入

This commit is contained in:
HapeLee
2025-09-26 11:36:43 +08:00
parent 795fc4e278
commit 2c1ca1b1e8
2 changed files with 106 additions and 25 deletions
@@ -1,8 +1,15 @@
package io.legato.kazusa.ui.widget.number
import android.app.AlertDialog
import android.content.Context
import android.view.View
import android.widget.LinearLayout
import android.widget.NumberPicker
import android.widget.TextView
import com.google.android.material.button.MaterialButton
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import io.legato.kazusa.R
import io.legato.kazusa.utils.hideSoftInput
@@ -10,9 +17,13 @@ import io.legato.kazusa.utils.hideSoftInput
class NumberPickerDialog(context: Context) {
private val builder = MaterialAlertDialogBuilder(context)
private var numberPicker: NumberPicker? = null
private var editText: TextInputEditText? = null
private var inputLayout: TextInputLayout? = null
private var tvRange: TextView? = null
private var maxValue: Int? = null
private var minValue: Int? = null
private var value: Int? = null
private var useInputMode = false
init {
builder.setView(R.layout.dialog_number_picker)
@@ -40,36 +51,64 @@ class NumberPickerDialog(context: Context) {
fun setCustomButton(textId: Int, listener: (() -> Unit)?): NumberPickerDialog {
builder.setNeutralButton(textId) { _, _ ->
numberPicker?.let {
it.clearFocus()
it.hideSoftInput()
listener?.invoke()
}
numberPicker?.clearFocus()
listener?.invoke()
}
return this
}
fun show(callBack: ((value: Int) -> Unit)?) {
builder.setPositiveButton(R.string.ok) { _, _ ->
numberPicker?.let {
it.clearFocus()
it.hideSoftInput()
callBack?.invoke(it.value)
}
}
builder.setPositiveButton(R.string.ok, null)
builder.setNegativeButton(R.string.cancel, null)
val dialog = builder.show()
numberPicker = dialog.findViewById(R.id.number_picker)
inputLayout = dialog.findViewById(R.id.til_input)
editText = dialog.findViewById(R.id.et_input)
tvRange = dialog.findViewById(R.id.tv_range)
val btnSwitch = dialog.findViewById<MaterialButton>(R.id.btn_switch_input)
numberPicker?.let { np ->
minValue?.let {
np.minValue = it
minValue?.let { np.minValue = it }
maxValue?.let { np.maxValue = it }
value?.let { np.value = it }
}
tvRange?.text = "输入范围: ${numberPicker?.minValue} - ${numberPicker?.maxValue}"
btnSwitch?.setOnClickListener {
useInputMode = !useInputMode
if (useInputMode) {
numberPicker?.visibility = View.GONE
inputLayout?.visibility = View.VISIBLE
tvRange?.visibility = View.VISIBLE
editText?.setText(numberPicker?.value?.toString() ?: value?.toString())
} else {
numberPicker?.visibility = View.VISIBLE
inputLayout?.visibility = View.GONE
tvRange?.visibility = View.GONE
inputLayout?.error = null
}
maxValue?.let {
np.maxValue = it
}
value?.let {
np.value = it
}
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.setOnClickListener {
if (useInputMode) {
val num = editText?.text?.toString()?.toIntOrNull()
val min = minValue ?: numberPicker?.minValue ?: Int.MIN_VALUE
val max = maxValue ?: numberPicker?.maxValue ?: Int.MAX_VALUE
if (num == null || num !in min..max) {
inputLayout?.error = "请输入 $min - $max 范围内的数字"
} else {
inputLayout?.error = null
callBack?.invoke(num)
dialog.dismiss()
}
} else {
numberPicker?.let {
it.clearFocus()
callBack?.invoke(it.value)
dialog.dismiss()
}
}
}
}
}
}
@@ -1,13 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:padding="24dp"
android:gravity="center">
<NumberPicker
android:id="@+id/number_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scrollbars="none" />
android:scrollbars="none"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="@id/btn_switch_input"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</FrameLayout>
<TextView
android:id="@+id/tv_range"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/til_input"
app:layout_constraintStart_toStartOf="@id/til_input"/>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginEnd="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_switch_input"
app:layout_constraintTop_toBottomOf="@id/btn_switch_input"
app:layout_constraintBottom_toTopOf="@id/btn_switch_input">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_switch_input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/ic_swap_horiz"
style="@style/Widget.Material3Expressive.Button.IconButton.Outlined"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>