Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/216.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用TextWatcher和LiveData在EditText中的光标位置?_Android_Android Edittext_Onchange_Android Livedata_Textwatcher - Fatal编程技术网

Android 使用TextWatcher和LiveData在EditText中的光标位置?

Android 使用TextWatcher和LiveData在EditText中的光标位置?,android,android-edittext,onchange,android-livedata,textwatcher,Android,Android Edittext,Onchange,Android Livedata,Textwatcher,我正在使用kotlin在android应用程序上创建一个表单。表单的每个字段都与livedata关联,以立即验证或更新数据。为了获得这个结果,我使用了一个textwatcher,它会在每次文本更改时更新相关的livedata。问题是,每次更新时,它都会将光标放在字段的开头,从而无法连续写入 我将代码中最有趣的部分粘贴到这里: 活动 viewModel.name.observe(lifecycleOwner, Observer { nameValue-> b

我正在使用kotlin在android应用程序上创建一个表单。表单的每个字段都与livedata关联,以立即验证或更新数据。为了获得这个结果,我使用了一个textwatcher,它会在每次文本更改时更新相关的livedata。问题是,每次更新时,它都会将光标放在字段的开头,从而无法连续写入

我将代码中最有趣的部分粘贴到这里:

活动

     viewModel.name.observe(lifecycleOwner, Observer { nameValue->
            binding.nameEditText.setText(
                nameValue?.toString()
            )
            binding.nameTextInputLayout.error =
                viewModel.nameError.value
        })
     viewModel.price.observe(lifecycleOwner, Observer { priceValue->
            binding.priceEditText.setText(
                price?.toString()
            )
            binding.priceTextInputLayout.error =
                viewModel.priceError.value
        })

binding.nameEditText.addTextChangedListener(
        TextFieldValidation(
            binding.nameEditText
        )
    )
binding.priceEditText.addTextChangedListener(
        TextFieldValidation(
            binding.priceEditText
        )
    )


  inner class TextFieldValidation(private val view: View) : TextWatcher {
        override fun afterTextChanged(s: Editable?) {}
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            when (view.id) {
                R.id.nameEditText-> {
                    viewModel.onNameChanged(s.toString())
                    viewModel.isNameValid()
                }
                R.id.priceEditText-> {
                    viewModel.onPriceChanged(s.toString())
                    viewModel.isPriceValid()
                }
     }
}
视图模型

var name = MutableLiveData<String>()
var price = MutableLiveData<Double>()

var nameError = MutableLiveData<String>()
var priceError = MutableLiveData<String>()

fun onNameChanged(newValue: String?) {
    if ((name.value != newValue)) {
        name.value = newValue
    }
}
fun onPriceChanged(newValue: Double?) {
    if ((price.value != newValue)) {
        price.value = newValue
    }
}

fun isNameValid() : Boolean {

    return if ((name.value == null) || (name.value == "")) {
        nameError.value = "Error"
        false
    } else {
        nameError.value = ""
        true
    }
}
fun isPriceValid() : Boolean {

    return if ((price.value == null) || (price.value == "")) {
        priceError.value = "Error"
        false
    } else {
        priceError.value = ""
        true
    }
}
var name=MutableLiveData()
var price=MutableLiveData()
var namererror=MutableLiveData()
var priceError=MutableLiveData()
更改了名称(新值:字符串?){
如果((name.value!=newValue)){
name.value=newValue
}
}
价格变化的乐趣(新价值:双倍?){
如果((price.value!=newValue)){
price.value=newValue
}
}
fun isNameValid():布尔值{
返回if((name.value==null)| |(name.value==“”){
namererror.value=“Error”
假的
}否则{
nameError.value=“”
真的
}
}
fun isPriceValid():布尔值{
如果((price.value==null)| |(price.value==“”)返回{
priceError.value=“错误”
假的
}否则{
priceError.value=“”
真的
}
}
XML

<com.google.android.material.textfield.TextInputLayout

            android:id="@+id/nameTextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <EditText
                android:id="@+id/nameEditText"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:backgroundTint="@color/white"
                android:inputType="text" />
        </com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout

            android:id="@+id/priceTextInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <EditText
                android:id="@+id/priceEditText"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:backgroundTint="@color/white"
                android:inputType="numberDecimal" />
        </com.google.android.material.textfield.TextInputLayout>

我尝试使用“mEdittext.setSelection(mEdittext.length());” 有人能帮我吗


谢谢你的耐心和帮助

之所以会发生这种情况,是因为在ViewModel observer中,您正在将nameValue和priceValue设置回它们刚刚来自的EditText。您可以添加检查,而不是将未更改的值设置回EditText:

if ((nameValue?.toString() == binding.nameEditText.getText().toString()) == false) {
   binding.nameEditText.setText(nameValue?.toString())
}

不,我不能停止观察nameValue和priceValue,因为我有其他字段链接到这些字段的值。好的,我编辑了我的答案