在屏幕方向Android上恢复recyclerview滚动位置

时间:2018-08-23 04:14:40

标签: android android-recyclerview

我有recyclerview,其数据是从服务器加载的。它以x <- data.frame(a = 1:3, b = 2:4) mult <- function(a,b,n) (a + b) * n 作为GridLayout。在屏幕方向上,我想保留layoutmanager的滚动位置。我尝试了stackoverflow的许多解决方案。但是它不能正常工作。我的意思是“无法完美工作”,它在多次屏幕定向后无法保持正确的滚动位置。这是我的代码实现:

recyclerviewonSaveInstanceState

onRestoreInstanceState

设置数据后调用恢复状态:

@Override
    protected void onSaveInstanceState(Bundle outState) {
        listState = recyclerView.getLayoutManager().onSaveInstanceState();
        outState.putParcelable(Constants.POSITION, listState);
        super.onSaveInstanceState(outState);
    }


    protected void onRestoreInstanceState(Bundle state) {
        // Retrieve list state and list/item positions
        if (state != null) {
            listState = state.getParcelable(Constants.POSITION);
            Log.e(TAG, "list state not null");
        }
        super.onRestoreInstanceState(state);
    }

    private void restoreState() {
        Log.e(TAG, "restoreStated called");
        if (listState != null) {
            recyclerView.getLayoutManager().onRestoreInstanceState(listState);
            listState = null;
        }
    }

3 个答案:

答案 0 :(得分:0)

如果您在活动中具有回收站视图,请尝试将recyclerViewAdapter保存在活动的ViewModel中,并在方向更改时获取适配器并将其设置为recyclerview。

如果片段中有recyclerview,请尝试在方向更改时获得相同的片段

Fragment savedFragment = getSupportFragmentManager().findFragmentByTag("Fragment_having_recyclerview");

然后设置此片段,而不是创建相同片段的新实例

答案 1 :(得分:0)

您应该使用savedInstanceBundle而不是将其保存在某个变量中,因为当屏幕方向更改时,活动将被破坏并重新创建,因此所有活动状态都将被破坏并创建为新状态。

 @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      savedInstanceState.putInt("pos", mRecyclerView.getAdapterPosition()); // gives current recycle view position.
      super.onSaveInstanceState(savedInstanceState);
    }

然后在onCreate()中可以得到这样的职位。

       @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        ..
        ..
        mRecyclerView.setAdapter(mRecyclerAdapter);
        if(savedInstanceState != null){
          mRecyclerView.post(new Runnable() {
            @Override
            public void run() {
                int pos = savedInstanceState.getInt("pos");
                mRecyclerView.scrollToPosition(pos);     
            }
        });

      }  

}

像这样在您的Adapter类中创建getAdapterPosition()

private class ComponentRecycleAdapter extends RecyclerView.Adapter<ComponentHolder> {

  ComponentHoder myHolder = null;

        @Override
        public ComponentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.one_component_item_list, parent, false);
            return new ComponentHolder(view);
        }

        @Override
        public void onBindViewHolder(ComponentHolder holder, int position) {
            ..
            ..
            ..
            this.myHolder  = holder;
        }

        @Override
        public int getItemCount() {
                ..
        }
        public int getAdapterPosition(){
           return myHolder =! null ? myHolder.getAdapterPosition() : 0;
        }
    }

让我知道它是否有效。编码愉快:)

答案 2 :(得分:0)

尝试了很多解决方案后,这确实帮助我恢复了recyclerview的位置

  @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
            if (newConfig.orientation == SCREEN_ORIENTATION_LANDSCAPE || newConfig.orientation == SCREEN_ORIENTATION_USER) {            
                if(mRecyclerView!=null && mRecyclerView.getLayoutManager()!=null) {
                    mBundleRecyclerViewState = new Bundle();
                    mListState = mRecyclerView.getLayoutManager().onSaveInstanceState();
                    mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, mListState);
                }

            } else if (newConfig.orientation == SCREEN_ORIENTATION_PORTRAIT) {
                if (mBundleRecyclerViewState != null) {
                    new Handler().postDelayed(() -> {
                        if(mRecyclerView!=null && mRecyclerView.getLayoutManager()!=null) {
                            mListState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
                            mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState);
                        }

                    }, 100);
                }

            }
    }