MVVM在使用afterTextChanged功能时在EditText中的文本末尾设置光标

时间:2018-03-07 16:21:21

标签: android mvvm kotlin observable

我的问题是当我的编辑文本添加逗号光标将移动到文本的第一个时如何在使用ObservableField和mvvm时将光标始终设置在编辑文本的末尾这是我的xml

<EditText
    android:id="@+id/input_amount"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="@string/hint_amount"
    android:inputType="number"
    android:maxLines="1"
    android:text="@={viewmodel.amount}"
    android:afterTextChanged="@{viewmodel.afterTextChanged}"/>

这是我的观点模型

var amount = ObservableField<String>()
fun afterTextChanged(editable: Editable){
    var longValue : Long
    var originalText = editable.toString()
    if(originalText.isNullOrEmpty())
        return

    longValue = originalText.convertCurrencyToLong()
    amount.set(longValue.convertToCurrency())
}

这是我的帮手

object CurrencyHelper{
   const val SIMPLE_CURRENCY_SPLIT = ","
   const val SIMPLE_CURRENCY_STRING = "#,###"

   @JvmField val SIMPLE_CURRENCY_FORMAT = object : ThreadLocal<NumberFormat>(){
       override fun initialValue(): NumberFormat {
           return DecimalFormat(SIMPLE_CURRENCY_STRING)
       }
   }
}

fun Long.convertToCurrency(): String = CurrencyHelper.SIMPLE_CURRENCY_FORMAT.get().format(this)

fun String.convertCurrencyToLong() : Long = this.replace(CurrencyHelper.SIMPLE_CURRENCY_SPLIT.toRegex(), "").toLong()

3 个答案:

答案 0 :(得分:3)

你可以使用BindingAdapter

@BindingAdapter("cursorPosition")
@JvmStatic
fun setCursorPosition(editText: EditText, value: String?) {
    value ?: return
    editText.setSelection(value.length)
}

并在您的布局中使用

cursorPosition="@{viewmodel.amount}"

答案 1 :(得分:2)

您正在使用Editable进行操作。在这里你也可以替换文本。您无需重置EditText的全文。

fun afterTextChanged(editable: Editable){
    val oldText = editable.toString()
    if(oldText.isNullOrEmpty()) return
    val newText = originalText.convertCurrencyToLong().convertToCurrency()
    if (oldText == newText) return
    editable.replace(0, oldText.length, newText)
}

这样你也应该保留选择。如果不是,您可以直接将Selection.setSelection(editable, start, end)设置为Editable

答案 2 :(得分:0)

通常,您可以使用以下方法更改EditText光标的位置:EditText#setSelection(int index),例如:myEditText.setSelection(42)。请注意索引不要超过EditText的实际文本。

使用MVVM和数据绑定框架使它有点棘手。根据您的完整架构,您有两种选择。

如果你在viewModel中引用了View(例如Activity,Fragment,ViewHolder等),那么你可以只调用一个视图的方法,在它里面可以设置光标的位置,如上图所示

如果你没有对视图的引用,那么你将不得不使用这样的绑定适配器:

@BindingAdapter("android:afterTextChanged")
public static void setTextWatcher(EditText view, YourViewModel viewModel) {
  view.addTextChangeListener(new TextWatcher() {
    ... other methods
    public void afterTextChanged(Editable s) {
       viewModel.afterTextChanged(s);
       view.setSelection(s.length() - 1);
    }
  })
}

请注意,如果需要,您可以绑定任何类型的对象而不是viewModel。例如,您可以创建一个界面,以便不直接与ViewModel结合。