Android 使用TextWatcher和LiveData在EditText中的光标位置?
我正在使用kotlin在android应用程序上创建一个表单。表单的每个字段都与livedata关联,以立即验证或更新数据。为了获得这个结果,我使用了一个textwatcher,它会在每次文本更改时更新相关的livedata。问题是,每次更新时,它都会将光标放在字段的开头,从而无法连续写入 我将代码中最有趣的部分粘贴到这里: 活动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
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());”但是它不太好,因为如果我在字符串中间做出改变,它会把光标带到最后。即使在双字段中,它的行为也不正确。
我需要让光标始终在准确的位置?在字符串的中间添加、删除或写入的情况下。对于字符串和double都是
有人能帮我吗
谢谢你的耐心和帮助 之所以会发生这种情况,是因为在ViewModel observer中,您正在将nameValue和priceValue设置回它们刚刚来自的EditText。您可以添加检查,而不是将未更改的值设置回EditText:
if ((nameValue?.toString() == binding.nameEditText.getText().toString()) == false) {
binding.nameEditText.setText(nameValue?.toString())
}
不,我不能停止观察nameValue和priceValue,因为我有其他字段链接到这些字段的值。好的,我编辑了我的答案