如何从 RecyclerView 存储用户位置并使用 ScrollToPosition() 进行投射?
How do I store users position from RecyclerView and use ScrollToPosition() to cast it?
我正在使用 RecyclerView
在网格布局中显示电影海报。
我的目标是保存用户的位置,因此当他们旋转 phone 时,它会保存他们的位置。
movieGrid.scrollToPosition(10);
当 phone 旋转时,该行代码是唯一可以转到顶部以外的位置的代码行。
我试过了
layoutManager.scrollToPositionWithOffset(position[0], position[1]);
但是没有用。
这是我的 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);
}
}
}
尝试只保存位置并用它恢复。
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);
}
我正在使用 RecyclerView
在网格布局中显示电影海报。
我的目标是保存用户的位置,因此当他们旋转 phone 时,它会保存他们的位置。
movieGrid.scrollToPosition(10);
当 phone 旋转时,该行代码是唯一可以转到顶部以外的位置的代码行。
我试过了
layoutManager.scrollToPositionWithOffset(position[0], position[1]);
但是没有用。
这是我的 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);
}
}
}
尝试只保存位置并用它恢复。
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);
}