问题
I am using a RecyclerView
to display movie posters in a Gridlayout.
My goal is to save the position of the user, so when they rotate the phone it will save their position.
movieGrid.scrollToPosition(10);
That line of code has been the only line of code that works to go to a position other than the top when the phone rotates.
I have tried
layoutManager.scrollToPositionWithOffset(position[0], position[1]);
But it didnt work.
This is the complete code for my MainActivity.java
public class MainActivity extends AppCompatActivity implements
MainActivityInterface {
private static final String LOG_TAG = MainActivity.class.getSimpleName();
private String sortBy;
private MovieAdapter movieAdapter;
private RecyclerView movieGrid;
private GridLayoutManager layoutManager;
private TextView errorMessage;
private TextView noFavoritesView;
private ProgressBar loadingIndicator;
private static final String SORT_BY_MOST_POPULAR = "http://api.themoviedb.org/3/movie/popular?api_key=" + BuildConfig.THE_MOVIE_DB_API_KEY;
private static final String SORT_BY_HIGHEST_RATED = "http://api.themoviedb.org/3/movie/top_rated?api_key=" + BuildConfig.THE_MOVIE_DB_API_KEY;
private static final String SORT_BY_FAVORITES = "";
private List<Movie> mFavoriteMovies;
final String FAVORITE_TYPE = "favorite";
private String movieType = "normal type";
private ArrayList<Movie> mMovies = new ArrayList<>();
static final String STATE_SORT_TYPE = "sortType";
static final String STATE_SCROLL_POSITION = "scrollPos";
static final String STATE_SORT_INDEX = "sortIndex";
// Stored data for the favorites
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
movieGrid = findViewById(R.id.grid_view);
layoutManager = new GridLayoutManager(this, 2);
movieGrid.setLayoutManager(layoutManager);
movieAdapter = new MovieAdapter(this);
movieGrid.setAdapter(movieAdapter);
errorMessage = findViewById(R.id.empty_view);
loadingIndicator = findViewById(R.id.loading_indicator);
sortBy = "http://api.themoviedb.org/3/movie/popular?api_key=" + BuildConfig.THE_MOVIE_DB_API_KEY;
getMovies();
getFavoritesDisplayed();
}
public String getSortBy() {return sortBy;}
public MovieAdapter getMovieAdapter() {return movieAdapter;}
public TextView getErrorMessage() {return errorMessage;}
public ProgressBar getLoadingIndicator() {return loadingIndicator;}
public RecyclerView getMovieGrid() {return movieGrid;}
public void startDetailActivity (Movie movie) {
Intent intent = new Intent(this, Details.class);
boolean isFavorite = compareToFavorite(movie);
intent.putExtra("movie", movie);
intent.putExtra("isFavorite", isFavorite);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.sort_most_popular) {
sortBy = SORT_BY_MOST_POPULAR;
getMovies();
return true;
}
if (id == R.id.sort_highest_rated) {
sortBy = SORT_BY_HIGHEST_RATED;
getMovies();
return true;
}
if (id == R.id.sort_favorites) {
sortBy = SORT_BY_FAVORITES;
movieType = FAVORITE_TYPE;
getFavoritesDisplayed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void getFavoritesDisplayed() {
// GET LIST FROM MOVIE (Room Database)
FavoritesViewModel viewModel = ViewModelProviders.of(this).get(FavoritesViewModel.class);
viewModel.getFavorites().observe(this, new Observer<List<Movie>>() {
@Override
public void onChanged(@Nullable List<Movie> movies) {
mMovies = (ArrayList<Movie>) movies;
mFavoriteMovies = movies;
if (movieType.equals(FAVORITE_TYPE)) {
Log.d(LOG_TAG, "Updating list of favorite movies from LiveData in ViewModel");
movieAdapter.setMovies(mMovies);
movieGrid.setAdapter(movieAdapter);
}
}
});
}
// CHECK TO SEE IF MOVIE IS IN FAVORITES
private boolean compareToFavorite(Movie movie) {
if (mFavoriteMovies != null) {
for (int i = 0; i < mFavoriteMovies.size(); i++) {
if (movie.getID().equals(mFavoriteMovies.get(i).getID())) {
return true;
}
}
}
return false;
}
private void getMovies() {
movieGrid.setVisibility(View.INVISIBLE);
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isConnectedOrConnecting()){
errorMessage.setVisibility(View.INVISIBLE);
loadingIndicator.setVisibility(View.VISIBLE);
new GetMoviesTask().execute(this);
} else {
errorMessage.setVisibility(View.VISIBLE);
loadingIndicator.setVisibility(View.INVISIBLE);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putIntArray("SCROLL_POSITION", new int[]{ movieGrid.getScrollX(), movieGrid.getScrollY()});
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
final int[] position = savedInstanceState.getIntArray("SCROLL_POSITION");
if(position != null) {
movieGrid.postDelayed(new Runnable() {
public void run() {
movieGrid.scrollToPosition(10);
}
}, 300);
}
}
}
回答1:
Try saving just the position and restore with that instead.
private static final String SCROLL_POSITION = "SCROLL_POSITION";
@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);
}
来源:https://stackoverflow.com/questions/54015021/how-do-i-store-users-position-from-recyclerview-and-use-scrolltoposition-to-ca