现在数值选择可以直接输入
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user