设置DigitsKeyListener时,小数点分隔符不可见

时间:2018-08-28 13:22:18

标签: android kotlin android-edittext

我想允许用户根据区域输入带小数点的数字(逗号或点)。

现在我正在使用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

您对在逗号键盘上使用逗号作为分隔符有任何想法吗?

3 个答案:

答案 0 :(得分:2)

我曾经遇到过同样的问题。三星设备上的普通键盘太可怕了……根本无法显示带有逗号的数字键盘。

我发现最好的解决方案是通过TextWatcher用逗号替换点。
但前提是默认语言环境的小数点分隔符是逗号。

digits中允许点(。)和逗号(,),并在XML中将inputType设置为numberDecimal

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

然后将TextWatcher添加到此editText:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    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)
                }
            }
        })
    }
}

issue已在Android O中修复,因此如果低于O,我们只需要这样做。
然后,使用以下命令获取字符串的实际编号:

try {
    val price = DecimalFormat.getInstance().parse(editTextPrice.text.toString());
} catch (e: ParseException) {
    e.printStackTrace()
    editText_price.setError(getString(R.string.error))
}

答案 1 :(得分:1)

问题是DigitsKeyListener does not specify the decimal/signed flag与带有接受字符串的getInstance一起使用时。由于KeyListener会覆盖EditText的输入类型,因此在设置KeyListener之后,您的EditText现在具有inputType编号,而不是numberDecimal或numberSigned。

由于DigitsKeyListener非常有用,因此一个简单的修复方法是简单地委派给它,但使用正确的输入类型。在Kotlin中,这非常简单:

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)

我建议您始终接受“。”除了任何特定于语言环境的分隔符之外,因为并非所有键盘实际上都会显示逗号或其他符号。

答案 2 :(得分:0)

公共类MainActivity扩展了活动{

private EditText editText;
private String blockCharacterSet = "~#^|$%&*!";

private InputFilter filter = new InputFilter() {

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {

        if (source != null && blockCharacterSet.contains(("" + source))) {
            return "";
        }
        return null;
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    editText = (EditText) findViewById(R.id.editText);
    editText.setFilters(new InputFilter[] { filter });
}

}