Почему onChanged не вызывается при изменении значения в списке LiveData?

контекст

С помощью MutableLiveData<List<Integer>> держать ценности. Когда первое значение (используя первое значение в качестве примера для краткости) в List увеличивается, TextView следует обновить в onChanged отобразить первое значение в List,

цели

  • Увеличьте первое значение в List
  • Обновить TextView когда первый пункт List изменения

проблема

  1. На Button нажмите, первое значение в List увеличивается, но MutableLiveData.onChanged() не называется, почему это?
  2. Есть ли MutableLiveData отвечать только на его setValue метод?
  3. Может ли это быть решено с помощью List содержащий MutableLiveData Целые числа (т.е. 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);
    }
});

1 ответ

Решение

LiveData Наблюдаемые-х 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 должен вызываться в основном потоке

Другие вопросы по тегам