gpt4 book ai didi

java - 为什么 LiveData setValue 或 PostValue 在 View 中只触发一次 onChange?

转载 作者:太空宇宙 更新时间:2023-11-03 13:08:54 24 4
gpt4 key购买 nike

LiveData setValue 应该已经触发了 Activity 中的 onChanged 方法,但是它只在第一次调用,在我尝试进行分页之后,它中断并且不再调用 onChanged,尽管我的响应确实成功并且我在日志中看到它。 setValue/postValue 有什么问题?这是一个错误吗?我应该自己实现观察者模式吗?那么使用 LiveData 有什么意义呢?我的寻呼仅在这已经 2-3 天后不起作用.....

  1. MainActivity 类

     public class MainActivity extends AppCompatActivity 
    private MutableLiveData<List<Photo>> mLivePhotos;
    // some code...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    mLivePhotos = loadData();
    mLivePhotos.observe(this, photos -> {
    Log.d(TAG, "onChanged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    mProgressBar.setVisibility(View.GONE);
    mPhotos = photos;
    if (mIsInitialCall) {
    initiateAdapter();
    mIsInitialCall = false;
    } else {
    mAdapter.updateList(mPhotos.subList(mPageNumber, mPageNumber + 10));
    }
    });

    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    int lastPosition =
    mLayoutManager.findLastCompletelyVisibleItemPosition();
    Log.d(TAG, "onScrolled - lastPosition: " + lastPosition);
    if (lastPosition == mLayoutManager.getItemCount() - 1) {
    Log.d(TAG, "onScrolled - End of list?");
    loadData();
    }
    }
    });
    }

    private MutableLiveData<List<Photo>> loadData() {
    Log.d(TAG, "loadData");
    if (mArticleViewModel == null) return null;
    mPageNumber += 10;
    mProgressBar.setVisibility(View.VISIBLE);
    return mArticleViewModel.loadPhotos();
    }
  2. View 模型

    public class ArticleViewModel extends ViewModel {
    private MutableLiveData<List<Photo>> photos;
    private ArticleRepository articleRepository;

    public MutableLiveData<List<Photo>> loadPhotos() {
    Log.d(TAG, "getArticleList");
    //TODO; add Dagger 2
    articleRepository = new ArticleRepository();
    photos = articleRepository.getPhotos();
    return photos;
    }
  3. 存储库

    public class ArticleRepository {

    public MutableLiveData<List<Photo>> getPhotos() {
    final MutableLiveData<List<Photo>> result = new MutableLiveData<>();
    Log.d(TAG, "getResults");
    ApiService.getService().getPhotos().enqueue(new Callback<List<Photo>>() {
    @Override
    public void onResponse(Call<List<Photo>> call, Response<List<Photo>> response) {
    Log.d(TAG, "onResponse");
    if (response.isSuccessful()) {
    Log.d(TAG, "isSuccessful");
    result.postValue(response.body());
    }
    }

    @Override
    public void onFailure(Call<List<Photo>> call, Throwable t) {
    Log.d(TAG, "onFailure: " + t.getMessage() + "\n" + t.getStackTrace());
    }
    });
    return result;
    }

最佳答案

Activity 不应该有任何 MutablieLiveData 成员变量,它应该在 ViewModel 中。

之所以它只在第一次起作用,是因为当您第一次观察到它通知更改的内容时,但是由于您的安排不正确,它再也不会更新。也就是说,因为 ArticleRepository 是在您的 ViewModel 中使用一组新的 MutableLiveData 重新创建的,所以您之前订阅的一个不再相关 - 您只需订阅一次 onCreate()

您应该将绑定(bind)与异步任务分开,例如 loadData() 它们不是一回事。绑定(bind)是您在开始时收集 MutableLiveData 所做的事情(您在 loadData 中所做的事情),但是一旦完成,您就不应该再做一次。

我还注意到您实际上在模型中使用了 LiveData,不建议这样做,因为它会破坏模式并可能带来其他问题。应该准备演示文稿的是 ViewModel,而不是存储库。由于您当前已经配置了一些东西,您的存储库也可以称为 ViewModel。相反,您应该做的是使用 observables 通知 ViewModel 一个新的批处理来发布或处理可能发生的错误。

研究这个例子:https://developer.android.com/topic/libraries/architecture/viewmodel

请注意,loadUsers() 在调用 getUsers() 时完成一次。这就是将 Activity 绑定(bind)到 ViewModel 的原因。但是 loadUsers() 可以稍后再次完成,并且应该将更改发布到 ViewModel 中的 LiveData。

关于java - 为什么 LiveData setValue 或 PostValue 在 View 中只触发一次 onChange?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50962210/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com