[英]How to send data from thread inside a ViewModel to main Activity/Fragment?
[英]How to pass data from activity or fragment to viewmodel?
我正在创建一个项目,在该项目中我使用 themoviedb api 来获取数据。 为此,我使用 MVVM 架构。 从 MovieListFragment ,我想将诸如流行、top_rated 之类的类别传递给 MovieViewModel 以相应地过滤电影,但我得到的是空值。
这是 MovieListFragment 类:-
public class MovieListFragment extends Fragment {
private MovieViewModel movieViewModel;
private static final String BASE_URL = "https://api.themoviedb.org";
private static final String API_KEY = "API_KEY";
private String category;
private GridView gridView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movie_list, container, false);
gridView = rootView.findViewById(R.id.images_grid_view);
movieViewModel = ViewModelProviders.of(this).get(MovieViewModel.class);
movieViewModel.setCategory(category); // from here i am passing value
movieViewModel.getMoviesRepository().observe(getActivity(), new Observer<MovieResults>() { // error line no :- 76
@Override
public void onChanged(MovieResults movieResults) {
final List<MovieResults.ResultsBean> listOfMovies = movieResults.getResults(); // error line no :- 79
MovieListAdapter mAdapter = new MovieListAdapter(getContext(), listOfMovies);
gridView.setAdapter(mAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallback.onImageSelected(position, listOfMovies);
}
});
}
});
return rootView;
}
public void setCategory(String category) {
this.category = category;
}
}
这是 MovieViewModel 类:-
public class MovieViewModel extends AndroidViewModel {
private String category;
private static final String API_KEY = "api_key";
private MovieRepository repository;
private MutableLiveData<MovieResults> listOfMovies;
public MovieViewModel(@NonNull Application application) {
super(application);
Log.d("MovieViewModel", category); // but here i am getting null value
listOfMovies = repository.getListOfMovies(category, API_KEY);
}
public MutableLiveData<MovieResults> getMoviesRepository() {
return listOfMovies;
}
public void setCategory(String category) {
this.category = category;
}
}
我收到这样的错误:-
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.mountblue.moviesapp.entity.MovieResults.getResults()' on a null object reference
at com.mountblue.moviesapp.fragment.MovieListFragment$2.onChanged(MovieListFragment.java:79)
at com.mountblue.moviesapp.fragment.MovieListFragment$2.onChanged(MovieListFragment.java:76)
如果您在movieViewModel.setCategory(category);
行中获得字符串category
null
值movieViewModel.setCategory(category);
,表示MovieListFragment
的字段category
为空。
尝试检查您是否在fragment
上调用了setCategory(String category)
方法。
如果不是这种情况,请详细说明错误。 例如它发生在哪条线上等等。
由于 Category 在 setter 之前由 MovieViewModel 的构造函数读取,因此它始终为 null。
作为方法参数的类别呢?
public class MovieViewModel extends AndroidViewModel {
private static final String API_KEY = "api_key";
private MovieRepository repository;
private MutableLiveData<MovieResults> listOfMovies = new MutableLiveData<MovieResults>();
public MovieViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<MovieResults> getMoviesRepository(category) {
loadData(category);
return listOfMovies;
}
private void loadData(category) {
// Do an asynchronous operation to fetch MovieResults.
repository.getListOfMovies(category, API_KEY);
...
// Receive asynchronous result in callback
// Post the result after getting the asynchronous result.
listOfMovies.postValue(response)
}
}
对于更详细的实现,需要一个存储库类。
文档: https : //developer.android.com/topic/libraries/architecture/viewmodel
您必须创建视图模型工厂才能将数据从活动或片段传递给视图模型。 您可以在此处参考。
在 MovieListFragment 类中:
首先删除这一行: movieViewModel.setCategory(category);
并在此处传递“类别”: movieViewModel.getMoviesRepository(category)
如下代码:
movieViewModel.getMoviesRepository(category).observe(getActivity(), new Observer<MovieResults>() { // error line no :- 76
@Override
public void onChanged(MovieResults movieResults) {
final List<MovieResults.ResultsBean> listOfMovies = movieResults.getResults(); // error line no :- 79
MovieListAdapter mAdapter = new MovieListAdapter(getContext(), listOfMovies);
gridView.setAdapter(mAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCallback.onImageSelected(position, listOfMovies);
}
});
}
});
在 MovieViewModel 类中:
将这一行移到 getMoviesRepository(String category) listOfMovies = repository.getListOfMovies(category, API_KEY);
只需从MovieViewModel
类中删除类别变量和setCategory()
方法,如下所示:
public class MovieViewModel extends AndroidViewModel {
private static final String API_KEY = "api_key";
private MovieRepository repository;
private MutableLiveData<MovieResults> listOfMovies;
public MovieViewModel(@NonNull Application application) {
super(application);
}
public MutableLiveData<MovieResults> getMoviesRepository(String category) {
Log.d("MovieViewModel", category); // but here i am getting null value
listOfMovies = repository.getListOfMovies(category, API_KEY);
return listOfMovies;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.