如何在所有情况下保持Android GridView的位置?

如何在所有情况下保持Android GridView的位置?,android,gridview,Android,Gridview,我是Android新手,我正在学校项目中尝试完成以下任务: 我有一个用户可以无限滚动的电影网格视图。 当应用程序启动时,我获取前20部电影,每次用户滚动到网格底部时,我执行AsyncTask获取20部电影并将其添加到适配器 当用户单击一部电影时,他会转到一个新的子活动以查看电影的详细信息 在以下情况下,我无法保持GridView的滚动位置: 当用户转到“详细信息”活动并返回到电影的主要活动时 当用户更改设备方向时 在处理这两种情况时,我还需要考虑到,可能用户滚动了很多,适配器中有100部电影,当

我是Android新手,我正在学校项目中尝试完成以下任务:

我有一个用户可以无限滚动的电影网格视图。 当应用程序启动时,我获取前20部电影,每次用户滚动到网格底部时,我执行AsyncTask获取20部电影并将其添加到适配器

当用户单击一部电影时,他会转到一个新的子活动以查看电影的详细信息

在以下情况下,我无法保持GridView的滚动位置:

  • 当用户转到“详细信息”活动并返回到电影的主要活动时
  • 当用户更改设备方向时
  • 在处理这两种情况时,我还需要考虑到,可能用户滚动了很多,适配器中有100部电影,当他返回时,活动从一开始就开始,只有前20部电影,所以我可以滚动到他最后的位置

    有人能告诉我如何在我的项目中提供最好的用户体验,在任何情况下都不会丢失用户的滚动位置吗

  • 单击
    gridItem
    后,尝试不完成
    mainActivity
    ,这样当用户导航回
    mainActivity
    (从
    detailsActivity
    )时,他将拥有之前的所有数据

  • 您可以通过活动的生命周期回调来处理这种情况:

  • 您可以按如下方式获取当前可见的GridView项的位置:

    int mCurrentPosition = gridview.getFirstVisiblePosition(); 
    
    当发生方向更改时,将重新创建活动并经历以下阶段:

    onSaveInstanceState
    onRestoreInstanceState

    然后,您可以在发生方向更改之前保存位置,并在恢复位置时将其取回

    保存您的活动状态

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current scroll state
    savedInstanceState.putInt(STATE_POSITION, mCurrentPosition);
    
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
    }
    
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Always call the superclass so it can restore the view hierarchy
        super.onRestoreInstanceState(savedInstanceState);
    
        // Restore state members from saved instance
        mCurrentPosition = savedInstanceState.getInt(STATE_POSITION);
    }
    
    恢复您的活动状态

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current scroll state
    savedInstanceState.putInt(STATE_POSITION, mCurrentPosition);
    
    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
    }
    
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Always call the superclass so it can restore the view hierarchy
        super.onRestoreInstanceState(savedInstanceState);
    
        // Restore state members from saved instance
        mCurrentPosition = savedInstanceState.getInt(STATE_POSITION);
    }
    
    在这里,一旦您拥有上一个位置,就可以在gridView中移动到所需的位置:

    gridview.smoothScrollToPosition(int mCurrentPosition)
    
    这来自android文档:

    将gridView滚动到位置

    我不知道这是否是最佳做法,但在我的情况下是这样的。 我决定将适配器设置为一个全局静态变量,这样我就可以维护通过API加载的数据量,并且不需要每次用户在活动之间移动时都执行请求。 为了保持滚动位置,我在移动到“详细信息”活动时使用了
    onItemClickListener
    ,在更改方向时使用了
    savedInstanceState

    以下是我的代码:

    //Static variables
    private static MoviesAdapter mMoviesAdapter;
    private static int mGridViewPosition = 0;
    
    //Call this method when user clicks the back button
    public static void ClearStaticData(){
        mMoviesAdapter.clear();
        mMoviesAdapter = null;
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState) {
        int index = mGridView.getFirstVisiblePosition();
        outState.putInt(GRID_VIEW_POSITION, index);
        super.onSaveInstanceState(outState);
    }
    
    @Override
    public View onCreateView(...) {
        if (mMoviesAdapter == null) {
            mMoviesAdapter = new MoviesAdapter(...);
        } else {
            RestoreGridPosition();
        }
    }
    
    private void RestoreGridPosition(){
        if(mGridViewPosition > 0 && mMoviesAdapter.getCount() >= mGridViewPosition)
            mGridView.setSelection(mGridViewPosition);
    }
    

    由于我通过API调用填充适配器,因此我认为这可能是保存数据而不是每次都执行请求的最佳解决方案。

    谢谢您的回答。你能告诉我怎么做吗。“单击gridItem后未完成mainActivity”?2.
    gridview.getFirstVisiblePosition()
    有时会显示半滚动项目的位置,但效果不太好…因为我使用的是片段,所以我似乎没有
    onRestoreInstanceState
    事件。你是对的。检查以下各项,你是对的。检查以下各项。关于不完成活动-如果在未调用
    MainActivity.finish()
    的情况下启动
    DetailsActivity
    ,则该活动应位于后堆栈中,并且当用户返回时,应将其返回到前一状态。