如何在另一个活动的背压下保留Recycler视图的滚动位置?

时间:2016-01-28 07:12:34

标签: android android-recyclerview

我看到很多关于这个话题的相关问题,但没有一个能帮助我。我正在使用 StaggeredGridLayout 作为我的RecyclerView(显示)。 每个CardView都会打开一个新活动,我面临的问题是,在新活动的背面按下,RecyclerView会滚动回到顶部。我希望它保留以前滚动的位置。

这就是我现在用来设置布局:

rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
rv.setHasFixedSize(true);

为新手提供适当的解决方案吗?

编辑:

   @Override
 protected void onResume() {
     super.onResume();
    if (listState != null) {
        rvlayout.onRestoreInstanceState(listState);
    }
      initializeData();

 }

布局:

RecyclerView.LayoutManager rvlayout = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);

和initializeData:

 public void initializeData() {

    rv.setLayoutManager(rvlayout);
    rv.setHasFixedSize(true);
    persons.clear();

    c = db.rawQuery(SELECT_SQL, null);
    c.moveToFirst();

    if (!c.moveToFirst())
    return;


    while (!c.isLast()) {
        id = c.getString(0);
        names = c.getString(1);
        age = c.getString(2);
        persons.add(new Person(id,names,age));
        c.moveToNext();
    }

    adapter = new RVAdapter(persons);
    rv.setAdapter(adapter);

}

5 个答案:

答案 0 :(得分:6)

正确的方法是保存RecyclerView滚动位置的状态,并在活动之间切换时恢复它。

1。要保存它,请覆盖onSaveInstanceState()

protected void onSaveInstanceState(Bundle state) {
    super.onSaveInstanceState(state);

    state.putParcelable(LIST_STATE_KEY, layoutManager.onSaveInstanceState());
}

2。要检索数据覆盖onRestoreInstanceState()

protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);

    Parcelable listState = state.getParcelable(LIST_STATE_KEY);
}

3。最后在onResume()方法

中更新LayoutManager
@Override
protected void onResume() {
    super.onResume();

    if (listState != null) {
        layoutManager.onRestoreInstanceState(listState);
    }
}

答案 1 :(得分:1)

如果您不再次加载列表(按后退按钮),回收站视图滚动应位于相同位置。你是否在onResume()中重新加载列表?

<强>更新

我刚刚尝试过我在下面的评论中提到的解决方案,但没有结果。我希望这段代码示例能为您提供帮助:

private int scrollPosition = 0;
private boolean shouldKeepScrollPosition = true;

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if(shouldKeepScrollPosition) {
                MyFragment.this.scrollPosition += dy;
            }
        }
    });

在重新加载数据之前,请执行以下操作:

shouldKeepScrollPosition = false;

重装数据后:

shouldKeepScrollPosition = true;
recyclerView.scrollBy(0, scrollPosition);

答案 2 :(得分:0)

不知道为什么会这样......但你可以使用startActivityForResult。在调用方法之前,请确保在列表中保存单击的位置。

覆盖具有网格布局的Activity中的onActivityResult并在那里调用mRecyclerView.scrollToPosition(mLastScrolledPosition)。

答案 3 :(得分:0)

使用
    rv.smoothScrollToPosition(位置);或
    rv.scrollToPosition(位置);

保持滚动位置。当你打开新活动时保存变量,共享偏好中的位置。并在initializeData()中调用rv.smoothScrollToPosition(position)或rv.scrollToPosition(position);

答案 4 :(得分:0)

尝试在 Oncreate 片段方法中添加 setRetainInstance(true),如下所示:

public function close_bid()
{
    $status = 'Assign';


    $this->db->where('bid_status',$status);

    return $this->db->get("project_bid")->result();
}

setRetainInstance(boolean retain)方法控制是否在重新创建活动时保留片段实例(例如从配置更改中)。