为什么在 LiveData 列表中更改值时不调用 onChanged?
Why is onChanged not called when value changed in LiveData List?
上下文
使用MutableLiveData<List<Integer>>
来保存一个值。当 List
中的第一个值(为简洁起见,使用第一个值作为示例)递增时,TextView
应在 onChanged
中更新以显示 List
中的第一个值。
目标
- 增加
List
中的第一个值
- 当
List
的第一项更改时更新 TextView
问题
- 单击
Button
时,List
中的第一个值递增,但未调用 MutableLiveData.onChanged()
,这是为什么?
MutableLiveData
是否只响应它的setValue
方法?
- 这可以通过包含
MutableLiveData
个整数的 List
来解决吗(即 MutableLiveData<List<MutableLiveData<Integer>>
,有问题,因为 List
中的每个项目都需要监听器)?
- 是否有更好的方法来实现目标?
代码
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 必须在主线程中调用
上下文
使用MutableLiveData<List<Integer>>
来保存一个值。当 List
中的第一个值(为简洁起见,使用第一个值作为示例)递增时,TextView
应在 onChanged
中更新以显示 List
中的第一个值。
目标
- 增加
List
中的第一个值
- 当
List
的第一项更改时更新TextView
问题
- 单击
Button
时,List
中的第一个值递增,但未调用MutableLiveData.onChanged()
,这是为什么? MutableLiveData
是否只响应它的setValue
方法?- 这可以通过包含
MutableLiveData
个整数的List
来解决吗(即MutableLiveData<List<MutableLiveData<Integer>>
,有问题,因为List
中的每个项目都需要监听器)? - 是否有更好的方法来实现目标?
代码
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 必须在主线程中调用