当前位置: 首页 > 知识库问答 >
问题:

ViewModel/LiveData/Observer设计

卢开济
2023-03-14

我的应用程序获取顶级评级或最受欢迎的电影从themoviedb.org.

我正在尝试用LiveData实现ViewModel来切换这两个按钮。在MainViewModel中。java,我有这个:


    //private static long String TAG = MainViewModel.class.getSimpleName();
    public LiveData<List<MovieRoom>> movies;
    private AppDatabase database;


    /*
        Use constructor to initialize all data that UI needs to populate
     */
    public MainViewModel(@NonNull Application application) {
        super(application);

        // how do I know this was initialized correctly?
        database = AppDatabase.getInstance(this.getApplication());
        //database = AppDatabase.getInstance(application);
        //movies is null after calling ViewModelProvider constructor

        // what are the values in movies?
        // _movieDao = null, mDatabase = null
        movies = database.movieDao().getAllMovies();
    }


    // Loads most popular movies
    public void loadData() {
        //MainViewModel.FetchMovieTask movies = new MainViewModel.FetchMovieTask();
        //movies.execute("popular");
        // Assign to movies
    }

    public void getAllMovies() {
        movies = database.movieDao().getAllMovies();
    }

    public void getPopularMovies() {
        movies = database.movieDao().getPopularMovies();
    }

    public void getTopRatedMovies() {
        movies = database.movieDao().getTopRatedMovies();
    }

    public void getFavoriteMovies() {
        movies = database.movieDao().loadFavoriteMovies(true);
    }

}

在我的主要活动中。java,按钮有一个onclick监听器,我将观察者设置为:

        b_pop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //updateMovies("popular");
                mViewModel.getPopularMovies();
            }
        });
mViewModel.movies.observe(this, new Observer<List<MovieRoom>>() {
            @Override
            public void onChanged(@Nullable List<MovieRoom> movieEntries) {
                //Log.d(TAG, "Receiving database update from LiveData");
                // mMovieAdapter.mMovies = 0
                mMovieAdapter.clear();
                // movieEntries = 0
                // mMovieAdapter mMovies = 0
                mMovieAdapter.setList(movieEntries);
                mMovieAdapter.notifyDataSetChanged();
            }
        });

问题是,当您将ViewModel的“电影”变量重新分配给最高等级或最受欢迎的电影列表时,它不会触发onChanged()。最高等级的电影列表与最受欢迎的电影列表相同,只是顺序不同。所以onChanged()永远不会被触发,我将无法将其设置为适配器。

我正在从0学习ViewModel、LiveData和observer,所以不知道如何重新设计它,使其能够工作?

共有1个答案

孔鸿远
2023-03-14

使用LiveData上的value将新获取的数据的值传递给ViewModel:

public void getAllMovies() {
        movies.setValue(database.movieDao().getAllMovies().getValue())
}

此外,您还需要可变的LiveData

public MutableLiveData<List<MovieRoom>> movies;
 类似资料:
  • 我读了文档,但在某些部分变得迷惑了。 ViewModel对象被设计为比views或LifeCycleOwners的特定实例化更长寿。这种设计还意味着您可以编写测试以更容易地覆盖ViewModel,因为它不知道视图和生命周期对象。ViewModel对象可以包含LifecycleObservers,如LiveData对象。但是,ViewModel对象绝不能观察到生命周期感知的可观察对象(如LiveDa

  • 我有一个单独的类来处理数据提取(特别是Firebase),我通常从它返回LiveData对象并异步更新它们。现在我希望将返回的数据存储在ViewModel中,但问题是为了获得所述值,我需要观察从数据提取类返回的LiveData对象。observe方法需要一个LifecycleOwner对象作为第一个参数,但我的ViewModel中显然没有这个对象,而且我知道我不应该在ViewModel中保留对ac

  • 我正在学习UDACITYs关于LiveData/Room/Persistence和Repository架构的Android教程。 在将所有代码粘在一起之后,我遇到了类型不匹配异常(我认为这是一个非常常见的问题)。 在课程示例中,创建了一个VideosRepository,成员videos是一个LiveData: 在模型中,我引入了一个MutableLiveData的_video 当我试图访问Liv

  • 此外,为什么Viewmodel不能观察到它自己的LiveData的变化?

  • 我正在寻找在中观察数据的最佳方法。 我正在使用MVVM数据绑定。 存储库: 它从服务器请求数据并返回实时数据。ViewModel必须观察数据更改。 视图模型: ViewModel使用一个来观察来自存储库的的变化。我添加了数据作为源来观察变化,并在它触发后将其删除,以防止在我多次获取数据时多次触发事件。并且必须有一个虚假的观察者来观察,因此触发器的onChange方法。 比方说,我只需要数据来隐藏/