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

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 package io.legato.kazusa.ui.widget.number
import android.app.AlertDialog
import android.content.Context import android.content.Context
import android.view.View
import android.widget.LinearLayout
import android.widget.NumberPicker 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.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.R
import io.legato.kazusa.utils.hideSoftInput import io.legato.kazusa.utils.hideSoftInput
@@ -10,9 +17,13 @@ import io.legato.kazusa.utils.hideSoftInput
class NumberPickerDialog(context: Context) { class NumberPickerDialog(context: Context) {
private val builder = MaterialAlertDialogBuilder(context) private val builder = MaterialAlertDialogBuilder(context)
private var numberPicker: NumberPicker? = null 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 maxValue: Int? = null
private var minValue: Int? = null private var minValue: Int? = null
private var value: Int? = null private var value: Int? = null
private var useInputMode = false
init { init {
builder.setView(R.layout.dialog_number_picker) builder.setView(R.layout.dialog_number_picker)
@@ -40,36 +51,64 @@ class NumberPickerDialog(context: Context) {
fun setCustomButton(textId: Int, listener: (() -> Unit)?): NumberPickerDialog { fun setCustomButton(textId: Int, listener: (() -> Unit)?): NumberPickerDialog {
builder.setNeutralButton(textId) { _, _ -> builder.setNeutralButton(textId) { _, _ ->
numberPicker?.let { numberPicker?.clearFocus()
it.clearFocus() listener?.invoke()
it.hideSoftInput()
listener?.invoke()
}
} }
return this return this
} }
fun show(callBack: ((value: Int) -> Unit)?) { fun show(callBack: ((value: Int) -> Unit)?) {
builder.setPositiveButton(R.string.ok) { _, _ -> builder.setPositiveButton(R.string.ok, null)
numberPicker?.let {
it.clearFocus()
it.hideSoftInput()
callBack?.invoke(it.value)
}
}
builder.setNegativeButton(R.string.cancel, null) builder.setNegativeButton(R.string.cancel, null)
val dialog = builder.show() val dialog = builder.show()
numberPicker = dialog.findViewById(R.id.number_picker) 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 -> numberPicker?.let { np ->
minValue?.let { minValue?.let { np.minValue = it }
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
} dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.setOnClickListener {
value?.let { if (useInputMode) {
np.value = it 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"?> <?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_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:padding="24dp"
android:gravity="center">
<NumberPicker <NumberPicker
android:id="@+id/number_picker" android:id="@+id/number_picker"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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>