android - 手机旋转时如何修复用户的保存位置

标签 android

我正在为类制作一个电影项目应用程序。该应用程序显示用户可以点击的海报。数据加载正常,但当我向下滚动并旋转手机时,应用程序会将我送回顶部,我将失去我的位置。我在这里错过了什么?

我已经尝试实现 onSavedInstanceState 和 onRestoreInstanceState 以使用“scrollPos”保存和恢复用户的位置,但它似乎不起作用。

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 ScrollView mScrollView;
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";
Bundle currInstanceState;


// Stored data for the favorites

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    currInstanceState = savedInstanceState;
    setContentView(R.layout.activity_main);
    //mScrollView = findViewById(R.id.main_scroll_view);
    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;
    onRestoreInstanceState(savedInstanceState);

    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) {

    outState.putInt(STATE_SCROLL_POSITION, layoutManager.findFirstCompletelyVisibleItemPosition());

    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        movieGrid.scrollToPosition(savedInstanceState.getInt(STATE_SCROLL_POSITION));
    }
}
}

我希望它能保存我滚动到的位置,所以当我旋转手机时,它会停留在我之前所在的同一区域,但当我旋转手机时,它会将我送回应用程序的顶部。

最佳答案

不要覆盖 onRestoreInstanceState(),也不要在 onCreate() 中调用它。在 onCreate() 中,您将获得名为 savedInstanceState 的 Bundle 参数。使用它来恢复 RecyclerView 位置,当 RecyclerView 创建时,滚动到该位置。

编辑 05.01.2019:

示例代码

public class Stackoverflow extends AppCompatActivity {

static final String STATE_SCROLL_POSITION = "scrollPos";

private RecyclerView recyclerView;
private MovieAdapter movieAdapter;
private GridLayoutManager gridLayoutManager;

private int lastPosition = 0;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if(savedInstanceState != null) {
        lastPosition = savedInstanceState.getInt(STATE_SCROLL_POSITION);
        // you can also restore here your list downloaded from web
    }

    recyclerView = findViewById(R.id.recycler_view);
    movieAdapter = new MovieAdapter(this);
    gridLayoutManager = new GridLayoutManager(this, 2);
    recyclerView.setAdapter(movieAdapter);
    recyclerView.setLayoutManager(gridLayoutManager);

    // you can scroll to your last position here if you'll save your
    // list data and restore if from Bundle, if not set this line
    // after you'll get your data again
    recyclerView.smoothScrollToPosition(lastPosition);

    /*getMovies();
    getFavoritesDisplayed();*/
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(STATE_SCROLL_POSITION, gridLayoutManager.findFirstCompletelyVisibleItemPosition());
    // you can also save here your list downloaded from web
}
}

关于android - 手机旋转时如何修复用户的保存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53937672/

相关文章:

android - 我想在我的 String JsonObject 中获取值(value)

android - 创建使用 Ionic Framework 编写的 Android 应用程序的 native 版本更新

android - 在 genymotion 上启动我的应用程序

android - 什么是 Android MultiDex?

Android 在 GooglePlayServices(游戏)连接上崩溃

php - Android Httpget超时

java - Proguard 保持集体诉讼禁止夏洛克

android - 任务 ':app:processDebugResources' 执行失败。 Gradle 构建失败

java - Android Volley 忽略参数无法连接

android - 有没有办法让 Android studio 格式化代码?