簡體   English   中英

旋轉后無法恢復滾動位置(RecyclerView)

[英]Can't restore scroll position after rotation (RecyclerView)

旋轉后無法恢復 RecyclerView 的滾動位置,並且在我關閉應用程序並再次打開它之后。 在第一種情況下,我可以在 Manifest 中使用android:configChanges ,但在我重新打開應用程序后它沒有幫助。 這是我的代碼。 嘗試恢復狀態后,我看到一個沒有列表的空屏幕。

public class MainActivity extends AppCompatActivity implements IMainContract.View {

    private final String BUNDLE_RECYCLER_LAYOUT = MainActivity.class.getSimpleName() + ".save.state.list";

    private IMainContract.Presenter mainPresenter;
    private MainAdapter adapter;
    private LinearLayoutManager layoutManager;

    private ImageView ivRefresh;
    private ProgressBar progressBar;
    private RecyclerView rvUsers;

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

        ivRefresh = (ImageView) findViewById(R.id.ivRefresh);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        rvUsers = (RecyclerView) findViewById(R.id.rvUsers);

        layoutManager = new LinearLayoutManager(this);
        rvUsers.setLayoutManager(layoutManager);

        mainPresenter = new MainPresenter(Repository.getInstance(this), this);

        adapter = new MainAdapter(new ArrayList<>(), this);
        rvUsers.setAdapter(adapter);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        ivRefresh.setOnClickListener(v -> mainPresenter.onRefreshPressed());

        if (savedInstanceState != null) {
            Parcelable savedRecyclerLayoutState = savedInstanceState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
            layoutManager.onRestoreInstanceState(savedRecyclerLayoutState);
        } else {
            mainPresenter.subscribe();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(BUNDLE_RECYCLER_LAYOUT, layoutManager.onSaveInstanceState());
    }
//...

}

您需要在 stackoverflow 上遵循此答案。更改您的代碼

public class MainActivity extends AppCompatActivity { 


    private final String KEY_RECYCLER_STATE = "recycler_state";

    private MainAdapter adapter;
    private LinearLayoutManager layoutManager;

    private ImageView ivRefresh;
    private ProgressBar progressBar;
    private RecyclerView rvUsers;
    private static Bundle mBundleRecyclerViewState;

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

        ivRefresh = (ImageView) findViewById(R.id.ivRefresh);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        rvUsers = (RecyclerView) findViewById(R.id.rvUsers);

        layoutManager = new LinearLayoutManager(this);
        rvUsers.setLayoutManager(layoutManager);


        adapter = new MainAdapter(new ArrayList<>(), this);
        rvUsers.setAdapter(adapter);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);




    } 


    @Override 
    protected void onPause() 
    { 
        super.onPause(); 

        // save RecyclerView state 
        mBundleRecyclerViewState = new Bundle();
        Parcelable listState = rvUsers.getLayoutManager().onSaveInstanceState();
        mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, listState);
    } 

      @Override 
    protected void onResume() 
    { 
        super.onResume(); 

        // restore RecyclerView state 
        if (mBundleRecyclerViewState != null) {
            Parcelable listState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
            rvUsers.getLayoutManager().onRestoreInstanceState(listState);
        } 
    } 


} 

您需要覆蓋onRestoreInstanceState()並使用保存的bundle設置recyclerView.getLayoutManager()

Parcelable savedRecyclerLayoutState ;

  @Override
    public void onRestoreInstanceState(@Nullable Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        if(savedInstanceState != null)
        {
            savedRecyclerLayoutState = savedInstanceState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
            rvUsers.getLayoutManager().onRestoreInstanceState(savedRecyclerLayoutState);
        }
    }

您還需要在您的活動中覆蓋onResume()

 @Override
protected void onResume() {
    super.onResume();

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

最初,您必須通過調用來獲取 RecyclerView 的當前滾動位置:

int index = rvUsers.getFirstVisiblePosition();

然后你必須在方向改變時保存這個值,當再次創建 RecyclerView 時,你必須將你的 RecyclerView 移動到這個索引。

我想這可以工作:

rvUsers.smoothScrollToPosition(int index)

如果您使用的是舊版本,請使用

setSelection(int position)

getFirstVisiblePosition() 

方法

您可以將位置存儲在共享首選項中,當您重新啟動應用程序時,從首選項中獲取值並相應地填充回收器視圖

使用已經填充的數據設置適配器很重要。 在這種情況下,位置會自動恢復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM