我想创建savedInstanceState,当显示旋转横向或纵向时会保存/保留数据,但是当我尝试旋转显示并在“空对象引用上显示错误”时,它会继续崩溃
这是我的适配器的一些代码:
public class ListMovieAdapter extends RecyclerView.Adapter<ListMovieAdapter.CardViewViewHolder> {
Context context;
ArrayList<Movie.ResultsBean> listMovie;
ProgressDialog progressBar;
public ListMovieAdapter(Context context, ArrayList<Movie.ResultsBean> listMovie) {
this.listMovie = listMovie;
this.context = context;
progressBar = new ProgressDialog(this.context);
}
public ArrayList<Movie.ResultsBean> getListMovie() {
return listMovie;
}
public void setListMovie(ArrayList<Movie.ResultsBean> movieList) {
this.listMovie = movieList;
notifyDataSetChanged();
}
这是我的一些Fragment代码:
public class MovieFragment extends Fragment {
View v;
private RecyclerView myrecyclerview;
private Parcelable mRecyclerState;
private ListMovieAdapter listMovieAdapter;
private ArrayList<Movie> listMovie = new ArrayList<>();
private MutableLiveData<ArrayList<Movie.ResultsBean>> dataMovies = new MutableLiveData<>();
private ProgressDialog progressBar;
public static String BASE_URL = "https://api.themoviedb.org";
public static String CATEGORY = "upcoming";
public static int PAGE = 1;
public static String API_KEY = "ce7feeb6af94d9372180d04db1bc755d";
public static String LANGUAGE = "en-US";
private static final String SAVEINSTANCE_RECYCLERSTATE = "RecyclerState";
private static final String SAVEINSTANCE_LIST = "movielist";
public MovieFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, @Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_movie, viewGroup, false);
myrecyclerview = v.findViewById(R.id.rv_fragmovie);
myrecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
progressBar = new ProgressDialog(getContext());
if (savedInstanceState == null) {
fetchJSON();
}else{
mRecyclerState = savedInstanceState.getParcelable(SAVEINSTANCE_RECYCLERSTATE);
listMovieAdapter.setListMovie((ArrayList)savedInstanceState.getParcelableArrayList(SAVEINSTANCE_LIST));
myrecyclerview.getLayoutManager().onRestoreInstanceState(mRecyclerState);
}
return v;
}
private void fetchJSON() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
Call<Movie> call = apiInterface.listOfMovie(CATEGORY, API_KEY, LANGUAGE, PAGE);
call.enqueue(new Callback<Movie>() {
@Override
public void onResponse(Call<Movie> call, Response<Movie> response) {
Movie results = response.body();
List<Movie.ResultsBean> listMovie = results.getResults();
ListMovieAdapter listMovieAdapter = new ListMovieAdapter(getContext(),
(ArrayList<Movie.ResultsBean>) listMovie);
myrecyclerview.setAdapter(listMovieAdapter);
}
@Override
public void onFailure(Call<Movie> call, Throwable t) {
showDialogLoad(false);
showDialogFail(true);
}
});
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listMovie = new ArrayList<>();
}
@Override
public void onSaveInstanceState(Bundle outState) {
mRecyclerState = myrecyclerview.getLayoutManager().onSaveInstanceState();
outState.putParcelable(SAVEINSTANCE_RECYCLERSTATE,mRecyclerState);
outState.putParcelableArrayList(SAVEINSTANCE_LIST,(ArrayList<? extends Parcelable>) listMovieAdapter.getListMovie());
super.onSaveInstanceState(outState);
}
然后一些错误日志:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.ilham.mymoviecatalogue.adapter.ListMovieAdapter.getListMovie()' on a null object reference
at com.ilham.mymoviecatalogue.fragment.MovieFragment.onSaveInstanceState(MovieFragment.java:106)
最佳答案
创建一个全局变量private static final String SCROLL_POSITION = "SCROLL_POSITION";
private RecyclerView movieGrid;
private GridLayoutManager layoutManager;
对于onSaveInstanceState
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SCROLL_POSITION, ((LinearLayoutManager)movieGrid.getLayoutManager()).findFirstVisibleItemPosition());
}
然后在下面添加:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
final int position = savedInstanceState.getInt(SCROLL_POSITION);
movieGrid.postDelayed(new Runnable() {
public void run() {
movieGrid.scrollToPosition(position);
}
}, 300);
}
请注意,最后一个数字
300
应该进行相应的调整,以测试它是否返回到最后一个位置,而不是旋转时将其重置到顶部。