【发布时间】:2022-01-14 09:41:47
【问题描述】:
在我的 ViewModel 类中,我有一个从 Internet 获取数据并通过 setValue() 将它们设置在 LiveData 上的方法(我使用了这些 docs 中的方法):
public class PageViewModel extends ViewModel {
private MutableLiveData<List<?>> mDataList;
...
private LiveData<List<?> getDataList() {
if (mDataList == null) {
mDataList = new MutableLiveData<>();
}
Handler handler = new Handler(Looper.getMainLooper());
// getData() connects to the internet and fetches the online data
mInternetConnection.getData(new InternetConnection.ConnectionCallback<List<?>>() {
@Override
public void onComplete(Result<List<?>> result) {
if (result instanceof Result.Success) {
mDataList.setValue(((Result.Success<List<?>>) result).data);
} else {
Log.e(LOG_TAG, "ViewModel could not obtain data list");
}
}
}, handler);
return mDataList;
}
但 mDataList.getValue() 为空。在主线程上调用setValue() 方法。
onComplete 肯定会被调用(选中)。
当我在onComplete 方法中检查mDataList 的值是否在setValue() 之后为空时,日志显示它不为空。
为什么是null,修改后的mDataList应该怎么取值?
我花了好几个小时在网上寻找解决方案,但找不到任何有用的东西。本站的相关问题也无助于解决问题。
编辑:
来自docs: 在此示例中,传递到存储库的 makeLoginRequest 调用的回调在主线程上执行。这意味着您可以直接从回调中修改 UI 或使用 LiveData.setValue() 与 UI 进行通信。
所以我遵循了这一点,但这部分:“或使用 LiveData.setValue() 与 UI 进行通信”不起作用。
在 Fragment 中设置了观察者,但 LiveData 仍未更新 - onChanged 中的 list 为空,屏幕保持空白,没有错误。
片段代码:
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentMainBinding.inflate(inflater, container, false);
View rootView = binding.getRoot();
binding.listRecyclv.setLayoutManager(new LinearLayoutManager(rootView.getContext()));
mAdapter = createAdapter(rootView.getContext(), pageViewModel.getList().getValue());
binding.listRecyclv.setAdapter(mAdapter);
pageViewModel.getList().observe(getViewLifecycleOwner(), new Observer<List<?>>() {
@Override
public void onChanged(@Nullable List<?> list) {
mAdapter.setList((ArrayList<MyObj>) list);
binding.listRecyclv.setAdapter(mAdapter);
}
}
}
});
ViewModel 中的 Getter:
public LiveData<List<?>> getList() {
return getDataList();
}
适配器中的代码:
public class AppAdapter extends RecyclerView.Adapter<AppAdapter.AppViewHolder> {
...
public void setList(ArrayList<MyObj> list) {
mAppList = list;
notifyDataSetChanged();
}
提前致谢。
【问题讨论】:
-
它不应该为空,因为您正在初始化方法中的值。也许您的意思是 LiveData 中的值为空。您可以在观察 LiveData 的位置显示代码吗?如果您确定 setValue 正在被调用但您没有看到更改,请确保变量的实例与您观察到的相同。
-
@juancamilo87 LiveData 本身由于某种原因为空。请看我的编辑,我已经发布了额外的代码
-
现在我已经修复了 LiveData - 它们不再为空,但它们的值为空
标签: android viewmodel android-livedata mutablelivedata