viewmodel在屏幕上进行网络呼叫方向更改android
我是android架构组件的新手,对viewmodel在屏幕上进行网络呼叫方向更改android,android,android-architecture-components,android-livedata,android-jetpack,android-viewmodel,Android,Android Architecture Components,Android Livedata,Android Jetpack,Android Viewmodel,我是android架构组件的新手,对viewmodel有点困惑。我正在构建一个应用程序,从服务器获取项目列表,并在布局中显示为列表。我已经在存储库类中实现了网络调用 Repository.java: //Get list of top rated movies public LiveData<NetworkResponse> getTopRatedMovies() { final MutableLiveData<NetworkResponse> r
viewmodel
有点困惑。我正在构建一个应用程序,从服务器获取项目列表,并在布局中显示为列表。我已经在存储库
类中实现了网络调用
Repository.java:
//Get list of top rated movies
public LiveData<NetworkResponse> getTopRatedMovies() {
final MutableLiveData<NetworkResponse> result = new MutableLiveData<>();
ApiService api = retrofit.create(ApiService.class);
Call<MovieData> call = api.getTopRateMovies("api_key");
call.enqueue(new Callback<MovieData>() {
@Override
public void onResponse(Call<MovieData> call, Response<MovieData> response) {
result.postValue(new NetworkResponse(response.body()));
}
@Override
public void onFailure(Call<MovieData> call, Throwable t) {
Log.e(TAG, t.getLocalizedMessage());
result.postValue(new NetworkResponse(t));
}
});
return result;
}
现在在MainActivity.java中:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
((MyApplication) getApplication()).getComponent().inject(this);
movieListViewModel = ViewModelProviders.of(this).get(MovieListViewModel.class);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
adapter = new MovieListAdapter(this);
movieListViewModel.getTopRatedMovieList();
observeTopRatedMovies();
}
private void observeTopRatedMovies() {
movieListViewModel.topRatedMovies.observe(this, new Observer<NetworkResponse>() {
@Override
public void onChanged(@Nullable NetworkResponse networkResponse) {
if (networkResponse.getPostData() != null) {
Log.e(TAG, "Successful");
topRatedData = networkResponse.getPostData();
adapter.addData(networkResponse.getPostData().getResults());
recyclerView.setAdapter(adapter);
} else {
Log.e(TAG, "failure");
}
}
});
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
把(这个)绑起来;
((MyApplication)getApplication()).getComponent().inject(此);
movieListViewModel=ViewModelProviders.of(this.get)(movieListViewModel.class);
recyclerView.setHasFixedSize(true);
setLayoutManager(新的GridLayoutManager(this,2));
适配器=新的MovieListAdapter(此);
movieListViewModel.GetToPatedMovieList();
观看预演电影();
}
私人无效观测预演电影(){
movieListViewModel.topRatedMovies.observe(这个,新的观察者(){
@凌驾
更改后的公共void(@Nullable NetworkResponse NetworkResponse){
if(networkResponse.getPostData()!=null){
Log.e(标记为“成功”);
topRatedData=networkResponse.getPostData();
adapter.addData(networkResponse.getPostData().getResults());
recyclerView.setAdapter(适配器);
}否则{
日志e(标签“故障”);
}
}
});
}
现在一切正常,我可以看到列表了。但是如果我旋转手机,viewmodel会再次进行网络通话。如何避免屏幕方向更改时再次进行网络呼叫?您只能初始化实时数据一次。这就足够了:
public class MovieListViewModel extends ViewModel {
public LiveData<NetworkResponse> result, topRatedMovies;
public LiveData<List<MovieEntity>> favoriteMovies;
private Repository repository;
public MovieListViewModel() {
repository = new Repository(MyApplication.getInstance());
topRatedMovies = repository.getTopRatedMovies();
}
}
公共类MovieListViewModel扩展了ViewModel{
公共现场数据结果,排名靠前的视频;
公共生活数据收藏;
私有存储库;
公共MovieListViewModel(){
repository=新存储库(MyApplication.getInstance());
topRatedMovies=repository.getTopRatedMovies();
}
}
我建议您使用无头片段设计模式。无头片段是保留其配置的片段,它不会膨胀任何xml。如果你旋转你的应用程序,这个片段将继续他的逻辑和配置,在你必须执行异步任务或异步调用时非常有用(就像你在改造中一样)
定义您的片段:
public class YourFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true); // <--------- the fragment retain his configuration
}
public void yourLogic(){
// do your logic
}
}
甚至这也是一个很好的方法。但我目前正在研究viewmodel和livedata的内容。也感谢您的这种方法。:)伟大的现在它不再在屏幕上进行网络调用了;是否有一种方法可以在不使用视图模型工厂的情况下传递id?可能存在重复的
public class YourFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true); // <--------- the fragment retain his configuration
}
public void yourLogic(){
// do your logic
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_yourHeadLessFragment= (YourFragment) getSupportFragmentManager().findFragmentByTag(HEADLESS_FRAGMENT);
if (_yourHeadLessFragment== null) {
_yourHeadLessFragment= new YourFragment();
_yourHeadLessFragment.setListener(this); // if you want a callback
getSupportFragmentManager().beginTransaction().add(_yourHeadLessFragment, HEADLESS_FRAGMENT).commit();
}
else{
_yourHeadLessFragment.setListener(this); // refresh the callbacks if a rotation happened
}
}
}