英文:
ViewModel/LiveData/Observer Design
问题
以下是翻译好的内容:
我的应用从themoviedb.org获取最受欢迎或最流行的电影。
public class MainViewModel extends AndroidViewModel {
public LiveData<List<MovieRoom>> movies;
private AppDatabase database;
/*
使用构造函数初始化UI需要填充的所有数据
*/
public MainViewModel(@NonNull Application application) {
super(application);
database = AppDatabase.getInstance(this.getApplication());
movies = database.movieDao().getAllMovies();
}
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);
}
}
在MainActivity.java中,按钮有一个点击监听器,我已经将观察者设置如下:
Button b_pop = (Button) findViewById(R.id.button_popular);
b_pop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mViewModel.getPopularMovies();
}
});
mViewModel.movies.observe(this, new Observer<List<MovieRoom>>() {
@Override
public void onChanged(@Nullable List<MovieRoom> movieEntries) {
mMovieAdapter.clear();
mMovieAdapter.setList(movieEntries);
mMovieAdapter.notifyDataSetChanged();
}
});
问题是,当您重新分配ViewModel的“movies”变量以获取最受欢迎或最流行的电影列表时,它不会触发onChanged()方法。最受欢迎的电影列表与最流行的电影列表相同,只是顺序不同。因此,onChanged()从未被触发,我将无法将其设置到适配器中。
我正在从零开始学习ViewModel、LiveData和观察者,所以不确定如何重新设计它以使其能够工作?
英文:
My app fetches Top Rated or Most Popular movies from themoviedb.org.
I'm trying to implement ViewModel with LiveData to toggle these two buttons. In MainViewModel.java, I have this:
//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);
}
}
In my MainActivity.java, the buttons have an onclick listener and I have set the observer as the following:
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();
}
});
Problem is, when you reassign the ViewModel's "movies" variable with top rated or most popular list of movies, it doesn't trigger onChanged(). The Top Rated list of movies is the same list of movies as the most popular, but just in different order. So onChanged() is never triggered and I will not be able to set it to the adapter.
I'm learning ViewModel, LiveData and observer from 0 so not sure how to redesign this so that it can work?
答案1
得分: 0
将新获取的数据的值通过 LiveData 的 value
传递给 ViewModel:
public void getAllMovies() {
movies.setValue(database.movieDao().getAllMovies().getValue());
}
同时你需要使用 MutableLiveData:
public MutableLiveData<List<MovieRoom>> movies;
英文:
Pass the value of newly fetched data to the ViewModel using value
on your LiveData:
public void getAllMovies() {
movies.setValue(database.movieDao().getAllMovies().getValue())
}
Also you need MutableLiveData
public MutableLiveData<List<MovieRoom>> movies;
专注分享java语言的经验与见解,让所有开发者获益!
评论