Merge pull request #1082 from hiqua/improve_number_picker

Make numpad work better in number picker dialog
pull/1107/head
Alinson S. Xavier 4 years ago committed by GitHub
commit 0e988e746c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,9 +19,11 @@
package org.isoron.uhabits.activities.common.dialogs
import android.annotation.SuppressLint
import android.content.Context
import android.content.DialogInterface
import android.text.InputFilter
import android.text.Spanned
import android.view.LayoutInflater
import android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE
import android.view.inputmethod.EditorInfo
@ -33,6 +35,7 @@ import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.InterfaceUtils
import java.text.DecimalFormatSymbols
import javax.inject.Inject
import kotlin.math.roundToLong
@ -40,18 +43,27 @@ class NumberPickerFactory
@Inject constructor(
@ActivityContext private val context: Context
) {
fun create(
value: Double,
unit: String,
callback: ListHabitsBehavior.NumberPickerCallback
): AlertDialog {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.number_picker_dialog, null)
val picker = view.findViewById<NumberPicker>(R.id.picker)
val picker2 = view.findViewById<NumberPicker>(R.id.picker2)
val tvUnit = view.findViewById<TextView>(R.id.tvUnit)
val watcherFilter: InputFilter = SeparatorWatcherInputFilter(picker2)
val numberPickerInputText = getNumberPickerInputText(picker)
// watch the unfiltered input before the filters remove a possible separator from it
numberPickerInputText.filters = arrayOf(watcherFilter).plus(numberPickerInputText.filters)
view.findViewById<TextView>(R.id.tvUnit).text = unit
view.findViewById<TextView>(R.id.tvSeparator).text =
DecimalFormatSymbols.getInstance().decimalSeparator.toString()
val intValue = (value * 100).roundToLong().toInt()
@ -61,19 +73,16 @@ class NumberPickerFactory
picker.wrapSelectorWheel = false
picker2.minValue = 0
picker2.maxValue = 19
picker2.setFormatter { v -> String.format("%02d", 5 * v) }
picker2.value = intValue % 100 / 5
refreshInitialValue(picker2)
tvUnit.text = unit
picker2.maxValue = 99
picker2.setFormatter { v -> String.format("%02d", v) }
picker2.value = intValue % 100
val dialog = AlertDialog.Builder(context)
.setView(view)
.setTitle(R.string.change_value)
.setPositiveButton(android.R.string.ok) { _, _ ->
picker.clearFocus()
val v = picker.value + 0.05 * picker2.value
val v = picker.value + 0.01 * picker2.value
callback.onNumberPicked(v)
}
.setOnDismissListener {
@ -89,20 +98,50 @@ class NumberPickerFactory
InterfaceUtils.setupEditorAction(
picker
) { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE)
if (actionId == EditorInfo.IME_ACTION_DONE) {
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
}
false
}
InterfaceUtils.setupEditorAction(
picker2
) { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
}
false
}
return dialog
}
private fun refreshInitialValue(picker: NumberPicker) {
// Workaround for Android bug:
// https://code.google.com/p/android/issues/detail?id=35482
@SuppressLint("DiscouragedPrivateApi")
private fun getNumberPickerInputText(picker: NumberPicker): EditText {
val f = NumberPicker::class.java.getDeclaredField("mInputText")
f.isAccessible = true
val inputText = f.get(picker) as EditText
inputText.filters = arrayOfNulls<InputFilter>(0)
return f.get(picker) as EditText
}
}
class SeparatorWatcherInputFilter(private val nextPicker: NumberPicker) : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence {
if (source == null || source.isEmpty()) {
return ""
}
for (c in source) {
if (c == DecimalFormatSymbols.getInstance().decimalSeparator || c == '.' || c == ',') {
nextPicker.performLongClick()
break
}
}
return source
}
}

@ -34,14 +34,13 @@
android:id="@+id/tvSeparator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="."/>
/>
<NumberPicker
android:id="@+id/picker2"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
/>
<TextView

Loading…
Cancel
Save