如何使EditText观察ViewModel的LiveData并在不使用数据绑定的情况下将用户输入转发到ViewModel

时间:2018-09-26 11:02:22

标签: android android-architecture-components

我正在尝试提出一种方法,使EditText更新ViewModel的数据,并同时观察该数据的任何更改(例如,通过操作数据库带来的更改)。有没有不用数据绑定库就能做到这一点的方法?

仅使用MutableLiveData时面临的主要问题如下:

当用户在EditText中输入文本时,TextWatcher戳ViewModel以更新其数据,这反过来会将新文本设置为MutableLiveData对象。由于EditText在观察LiveData,因此会触发onChange并相应地设置EditText的文本,这又将触发TextWatcher再次创建无限循环。

3 个答案:

答案 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(),它仅在设置新值时才会发射数据。