我正在尝试提出一种方法,使EditText更新ViewModel的数据,并同时观察该数据的任何更改(例如,通过操作数据库带来的更改)。有没有不用数据绑定库就能做到这一点的方法?
仅使用MutableLiveData时面临的主要问题如下:
当用户在EditText中输入文本时,TextWatcher戳ViewModel以更新其数据,这反过来会将新文本设置为MutableLiveData对象。由于EditText在观察LiveData,因此会触发onChange并相应地设置EditText的文本,这又将触发TextWatcher再次创建无限循环。
答案 0 :(得分:0)
我也遇到了这个问题,因为我不喜欢数据绑定库。我按照@kAliert所说的那样做,但是在我的ViewModel
中保持了逻辑。我只是在函数上添加了一个简单的陷阱,该函数在ViewModel
中接收我的文本更改事件。效果很好。
fun editTextChanged(newText: String) {
if (newText == textLiveData.value) {
return
}
}
答案 1 :(得分:0)
可能会晚一点,但希望对某些人有用。我遇到了这个问题,我所做的是考虑将viewmodel类的字符串成员维护为editText的最后一个值。每次返回实时数据时,它都会首先检查它是否有新的edittext输入(getData()参数)与其过去的值(保存在myVariable中)之间的差异:
public class MyViewModel extends ViewModel {
private MutableLiveData<DataType> data;
private String myVariable; //maintainer variable
public LiveData<DataType> getData(String input){
if(data == null || !myVariable.equals(input)){
myVariable = input;
data = new MutableLiveData<>();
loadData(data, input);
}
return data;
}
并在您的所有者(例如活动)中观察数据更改:
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
myViewModel.getData(s).observe(this, new Observer<DataType>() {
@Override
public void onChanged(<DataType> data) {
//do everything you want like update UI by data
}
});
}
@Override
public void afterTextChanged(Editable s) {
}
});
答案 2 :(得分:0)
我认为您还可以使用LiveData.distinctUntilChanged(),它仅在设置新值时才会发射数据。