android - 在 recyclerview 上更改方向期间再次从 Internet 加载数据
问题描述
有 RecyclerView 并且在方向更改期间我希望数据不会再次从 Internet 加载。你是怎样做的?
这是代码
package picodiploma.dicoding.database.picodiploma.dicoding.database.tv;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import java.util.ArrayList;
import java.util.List;
import picodiploma.dicoding.database.ApiClient;
import picodiploma.dicoding.database.ApiInterface;
import picodiploma.dicoding.database.R;
import retrofit2.Call;
import retrofit2.Callback;
import static android.view.View.VISIBLE;
/**
* A simple {@link Fragment} subclass.
*/
public class TvShow extends Fragment {
private static RecyclerView recyclerView;
private static final String API_KEY = "2e08750083b7e21e96e915011d3f8e2d";
private static final String TAG = TvShow.class.getSimpleName();
private static ProgressBar progressBar;
private static List<ResultsItem> resultsTv = new ArrayList<>();
private static TvShowRecyclerAdapter recyclerAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public TvShow() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_tv_show, container, false);
recyclerView = view.findViewById(R.id.recycler_tv);
progressBar = view.findViewById(R.id.progress_bar);
progressBar.setVisibility(VISIBLE);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
getData();
if (savedInstanceState == null) {
getData();
}
else {
resultsTv = savedInstanceState.getParcelableArrayList("tv");
recyclerAdapter.refill(resultsTv);
}
return view;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putParcelableArrayList("tv", (ArrayList<? extends Parcelable>) resultsTv);
super.onSaveInstanceState(outState);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_change_settings){
Intent mIntent = new Intent(Settings.ACTION_LOCALE_SETTINGS);
startActivity(mIntent);
}
return super.onOptionsItemSelected(item);
}
public void getData() {
ApiInterface apiInterface = ApiClient.getList().create(ApiInterface.class);
Call<Response> responseCall = apiInterface.getTvList(API_KEY);
responseCall.enqueue(new Callback<Response>() {
@Override
public void onResponse(Call<Response> call, retrofit2.Response<Response> response) {
resultsTv = response.body().getResults();
recyclerAdapter = new TvShowRecyclerAdapter(resultsTv, getContext());
recyclerView.setAdapter(recyclerAdapter);
recyclerView.setVisibility(VISIBLE);
progressBar.setVisibility(View.GONE);
}
@Override
public void onFailure(Call<Response> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Log.d(TAG, t.toString());
}
});
}
}
现在,方向改变后的 RecyclerView 再次从互联网加载数据。我想让它使用以前保存在 Fragment 上的数据。顺便说一句,Fragment 也连接到 MainActivity 上的 FragmentPagerAdapter。谢谢您的回答。
解决方案
处理这些情况的推荐方法 - 处理方向变化 - 无需从网络重新获取数据,是使用来自谷歌的 Android 架构组件的 ViewModel。
你ViewModel
可以像下面这样
public class YourViewModel extends ViewModel {
private MutableLiveData<List<ResultsItem>> resultsItem;
public LiveData<List< ResultsItem >> getData() {
if (resultsItem == null) {
resultsItem = new MutableLiveData<List<resultsItem>>();
loadData();
}
return resultsItem;
}
private void loadData() {
// Request your data from network
}
}
然后在你的Fragment
YourViewModel model = ViewModelProviders.of(this).get(YourViewModel.class);
model.getData().observe(this, resultsItem -> {
// here you can update UI - passing the list of data
});
推荐阅读
- javascript - 在正文负载上使用 javascript 检查用户浏览器
- python - 二叉树迭代中序遍历
- typescript - 如何在方法中使用“this”创建类的新实例?
- python - 从python中的xml文件中提取特定对象
- parallel-processing - 为什么并行处理比普通代码花费更长的时间?
- laravel - 在生产 Laravel Livewire 中出现错误
- python - np.dot 错误地从矩阵乘法更改为元素乘积
- python - python中针对特定情况的变量变量
- python - python 'AttributeError' 与 can.BLFReader
- docker - 如何将自定义环境变量添加到 docker-ejabberd