为什么在 LiveData 列表中更改值时不调用 onChanged?

Why is onChanged not called when value changed in LiveData List?

上下文

使用MutableLiveData<List<Integer>> 来保存一个值。当 List 中的第一个值(为简洁起见,使用第一个值作为示例)递增时,TextView 应在 onChanged 中更新以显示 List 中的第一个值。

目标

问题

  1. 单击 Button 时,List 中的第一个值递增,但未调用 MutableLiveData.onChanged(),这是为什么?
  2. MutableLiveData是否只响应它的setValue方法?
  3. 这可以通过包含 MutableLiveData 个整数的 List 来解决吗(即 MutableLiveData<List<MutableLiveData<Integer>>,有问题,因为 List 中的每个项目都需要监听器)?
  4. 是否有更好的方法来实现目标?

代码

final MutableLiveData<List<Integer>> vals = new MutableLiveData<>();
List<Integer> intVals = new ArrayList<>();
intVals.add(0);
vals.setValue(intVals);

tv.setText("" + vals.getValue().get(0));

vals.observe(this, new Observer<List<Integer>>() {
    @Override
    public void onChanged(@Nullable List<Integer> integers) {
        int firstVal = integers.get(0);
        Log.d(TAG, "onChanged val " + firstVal);
        tv.setText("" + firstVal);
    }
});

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // first val in List is incremented but onChanged isn't called, why?
        int newVal = vals.getValue().get(0) + 1;
        vals.getValue().set(0, newVal);
        Log.d(TAG, "set val at index 0 to " + newVal);
    }
});

LiveData Observable 的 onChanged 方法仅在调用 setValue() 之后调用,或者 postValue().setValue() 应该只从主线程调用,因为 postValue() 应该从主线程调用不同的线程(onClick 发生在主线程上,所以 setValue() 会发生)。 无论如何,使用下面的代码将为您提供所需的东西:

btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
    // first val in List is incremented but onChanged isn't called, why?
    List<Integer> temp = vals.getValue();
    if(temp!=null) // null-safety just in case....
    {
        int newVal = temp.get(0) + 1;
        temp.set(0, newVal);
        vals.setValue(temp);
        Log.d(TAG, "set val at index 0 to " + newVal);
    }
}
});

你应该调用 setValue 或 postValue 来更新 LiveData,否则它不会被观察到,主要是我希望你使用 postValue 因为 setValue 必须在主线程中调用