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