[英]Cannot restore Scroll position
Im stuck here 2 days. 我在这里停留了2天。 I am trying to restore scroll position after device rotation. 我试图在设备旋转后恢复滚动位置。
Im saving an arraylist in the onSaveInstance, adding the movies i have to it and trying to set the adapter. 即时通讯将数组列表保存在onSaveInstance中,向其中添加电影,然后尝试设置适配器。
If i switch shorting criteria and rotate the device, it scrolls up to the top and not retaining its position. 如果我切换短路标准并旋转设备,它会向上滚动到顶部,而不会保持其位置。 Here's my code 这是我的代码
public class MainActivity extends AppCompatActivity {
public static final String MOVIE_LIST = "instanceMovieList";
public static final String RECYCLER_VIEW_STATE_KEY = "RECYCLER_VIEW_STATE_KEY";
private static final String LOG_TAG = MainActivity.class.getSimpleName();
Context mContext;
Toolbar mToolBar;
@BindView(R.id.prefSpinnner)
Spinner prefSpinner;
@BindView(R.id.noDataTv)
TextView noDataTv;
@BindView(R.id.rv_movies)
RecyclerView mMoviesRV;
private AppDatabase mDb;
private String userOption = "Most Popular";
private ArrayList<Movie> mMoviesList = new ArrayList<>();
private MovieRecycleViewAdapter movieRecycleViewAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private Parcelable mListState;
@Override
protected void onSaveInstanceState(Bundle outState) {
if (mMoviesList != null) {
outState.putParcelableArrayList(MOVIE_LIST, mMoviesList);
mListState = mLayoutManager.onSaveInstanceState();
outState.putParcelable(RECYCLER_VIEW_STATE_KEY, mListState);
}
super.onSaveInstanceState(outState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
mMoviesRV.setLayoutManager(gridLayoutManager);
mMoviesRV.setHasFixedSize(true);
movieRecycleViewAdapter = new MovieRecycleViewAdapter(MainActivity.this, mMoviesList);
mMoviesRV.setAdapter(movieRecycleViewAdapter);
mLayoutManager = mMoviesRV.getLayoutManager();
if (savedInstanceState != null && savedInstanceState.containsKey(MOVIE_LIST)) {
ArrayList<Movie> savedMovieList = savedInstanceState.getParcelableArrayList(MOVIE_LIST);
Log.d(LOG_TAG, "getting movies from instance ");
mMoviesList.addAll(savedMovieList);
movieRecycleViewAdapter = new MovieRecycleViewAdapter(MainActivity.this, mMoviesList);
mMoviesRV.setAdapter(movieRecycleViewAdapter);
}
mToolBar = findViewById(R.id.toolbar);
mToolBar.setTitle(getResources().getString(R.string.app_name));
ArrayAdapter<String> spinAdapter = new ArrayAdapter<String>(MainActivity.this, R.layout.pref_spinner_item_list, getResources().getStringArray(R.array.userPrefs));
spinAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
prefSpinner.setAdapter(spinAdapter);
prefSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
userOption = prefSpinner.getSelectedItem().toString();
if (userOption.contentEquals("Most Popular") || userOption.contentEquals("Highest Rated")) {
PopulateMoviesTask newTask = new PopulateMoviesTask();
newTask.execute();
} else {
setUpViewModel();
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
PopulateMoviesTask newTask = new PopulateMoviesTask();
newTask.execute();
}
});
mDb = AppDatabase.getInstance(getApplicationContext());
}
private void setUpViewModel() {
MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
viewModel.getMovies().observe(this, new Observer<List<Movie>>() {
@Override
public void onChanged(@Nullable List<Movie> movies) {
Log.d(LOG_TAG, "updating list of movies from livedata in viewmodel");
movieRecycleViewAdapter.setMovies(movies);
}
});
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
mMoviesList = savedInstanceState.getParcelableArrayList(MOVIE_LIST);
mListState = savedInstanceState.getParcelable(RECYCLER_VIEW_STATE_KEY);
}
}
@Override
protected void onResume() {
super.onResume();
if (mListState != null) {
mLayoutManager.onRestoreInstanceState(mListState);
}
}
private class PopulateMoviesTask extends AsyncTask<URL, Void, String> {
@Override
protected String doInBackground(URL... urls) {
URL searchMovieObjectUrl = NetworkUtils.createUrl(userOption);
String jsonString = "";
try {
jsonString = NetworkUtils.makeHttpRequest(searchMovieObjectUrl);
} catch (IOException e) {
Log.e("Main Activity", "Problem making the HTTP request.", e);
}
return jsonString;
}
@Override
protected void onPostExecute(String jsonString) {
if (jsonString == null) {
mMoviesRV.setVisibility(View.GONE);
noDataTv.setVisibility(View.VISIBLE);
} else {
mMoviesRV.setVisibility(View.VISIBLE);
noDataTv.setVisibility(View.GONE);
mMoviesList = JsonUtils.extractFeatureFromJson(jsonString);
}
movieRecycleViewAdapter = new MovieRecycleViewAdapter(MainActivity.this, mMoviesList);
mMoviesRV.setAdapter(movieRecycleViewAdapter);
}
}
} }
Use this 用这个
private Parcelable recyclerViewState;// global 私有的Parcelable recyclerViewState; //全局
onResume 的onResume
@Override
public void onResume() {
super.onResume();
mMoviesRV.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
onPasue onPasue
@Override
public void onPause() {
super.onPause();
recyclerViewState= mMoviesRV.getLayoutManager().onSaveInstanceState();
}
Since i found out what was going on, i think i should post an answer. 既然我发现了正在发生的事情,我想我应该发布一个答案。
@Override protected void onSaveInstanceState(Bundle outState) {
if (mMoviesList != null) {
outState.putParcelableArrayList(MOVIE_LIST, mMoviesList);
mListState = mLayoutManager.onSaveInstanceState();
outState.putParcelable(RECYCLER_VIEW_STATE_KEY, mListState);
}
super.onSaveInstanceState(outState);
} }
is enough to save the moviesList through lifecycle and then retrieve it 足以保存整个生命周期中的movieList,然后将其检索
if (savedInstanceState != null && savedInstanceState.containsKey(MOVIE_LIST)) {
mMoviesList = savedInstanceState.getParcelableArrayList(MOVIE_LIST);
This answers the original question 这回答了原始问题
But the problem was in my adapter and WHEN i was initializing it. 但是问题出在我的适配器上,而我正在初始化它。 The adapter should only be initialized in onCreate (in my case at least) and then notify it if the Arraylist data changed more info here . 仅应在onCreate中初始化适配器(至少在我的情况下),然后在Arraylist数据更改了更多信息的情况下通知适配器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.