How do I store users position from RecyclerView an

2019-08-27 22:07发布

问题:

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);
}