Ключ десятичного разделителя не виден, если установлен DigitsKeyListener - PullRequest
0 голосов
/ 28 августа 2018

Я хочу разрешить пользователю вводить числа с десятичным разделителем (запятая или точка) в зависимости от региона.

Теперь я использую DigitsKeyListener, чтобы включить запятую в качестве разделителя для некоторых локалей (например, Польша, Германия).

val separator = DecimalFormatSymbols.getInstance().decimalSeparator
editTextValue.keyListener = DigitsKeyListener.getInstance("-0123456789$separator")

Этот код написан на .

Если программная клавиатура Gboard или другая сторонняя клавиатура, то все в порядке, и пользователь может использовать запятую или точку в качестве разделителя.

Но когда пользователь использует стандартную клавиатуру и установлен DigitsKeyListener, тогда не все клавиши видны, и пользователь не может добавить разделитель.

Это мой код EditText:

<android.support.design.widget.TextInputLayout
    android:id="@+id/textInput"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    app:hintTextAppearance="@style/Lorin.Theme.TextInputLayout"
    app:layout_constraintLeft_toRightOf="@id/imageInfo"
    app:layout_constraintRight_toLeftOf="@id/buttonHistoryNumeric">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/editTextValue"
        style="@style/Lorin.EditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:imeOptions="flagNavigateNext"
        android:inputType="number|numberSigned|numberDecimal"
        android:maxLines="1"
        tools:hint="Range"/>
</android.support.design.widget.TextInputLayout>

Keyboard without separator key


val separator = DecimalFormatSymbols.getInstance().decimalSeparator
//editTextValue.keyListener = DigitsKeyListener.getInstance("-0123456789$separator")

Когда закомментирована строка с DigitsKeyListener, ключ для разделителя виден, но доступен только разделитель точка Keyboard with separator key

У вас есть идеи, как использовать запятую в качестве разделителя на стандартной клавиатуре?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Проблема в том, что DigitsKeyListener не указывает десятичный / подписанный флаг при использовании getInstance со строкой принятых символов. Поскольку KeyListener переопределяет тип ввода EditText, после установки KeyListener ваш EditText теперь имеет номер inputType, а не numberDecimal или numberSigned.

Поскольку DigitsKeyListener весьма полезен, простое решение - просто делегировать его, но использовать правильный тип ввода. В Котлине это удивительно просто:

class DecimalSignedDigitsKeyListener(digitsKeyListener: DigitsKeyListener) : 
    KeyListener by digitsKeyListener {

  override fun getInputType() =
    InputType.TYPE_CLASS_NUMBER or 
    InputType.TYPE_NUMBER_FLAG_DECIMAL or 
    InputType.TYPE_NUMBER_FLAG_SIGNED
}


val separator = DecimalFormatSymbols.getInstance().decimalSeparator
val digitsKeyListener = DigitsKeyListener.getInstance("<your digits>")
editTextValue.keyListener = DecimalSignedDigitsKeyListener(digitsKeyListener)

Я бы рекомендовал всегда принимать '.' в дополнение к любому разделителю, зависящему от локали, поскольку не все клавиатуры фактически показывают запятую или другие символы.

0 голосов
/ 04 сентября 2018

Однажды у меня была такая же проблема. Стандартные клавиатуры на устройствах Samsung ужасны ... Нет возможности отобразить цифровую клавиатуру запятой.

Лучшее решение, которое я нашел, было просто заменить точку запятой через TextWatcher.
Но только если десятичный разделитель локали по умолчанию - запятая.

Разрешить обе точки (.) И запятую (,) в digits и установить inputType на numberDecimal в XML:

<EditText
        android:id="@+id/editText_price"
        android:layout_marginLeft="8dp"
        android:layout_marginStart="8dp"
        android:digits="1234567890,."
        android:imeOptions="actionDone"
        android:inputType="numberDecimal" />

А затем добавьте TextWatcher к этому тексту редактирования:

val separator = DecimalFormatSymbols.getInstance().decimalSeparator
if (separator == ',') {
    editText_price.addTextChangedListener(object : TextWatcher {
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit

        override fun afterTextChanged(s: Editable?) {
            if (s.toString().contains(".")) {
                val replaced = s.toString().replace('.', separator)
                editText_price.setText(replaced)
                editText_price.setSelection(replaced.length)
            }
        }
    })
}

Затем, чтобы получить фактический номер строки, используйте это:

try {
    val price = DecimalFormat.getInstance().parse(editTextPrice.text.toString());
} catch (e: ParseException) {
    e.printStackTrace()
    editText_price.setError(getString(R.string.error))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...