ViewHolder returns RecyclerView 中的旧位置
ViewHolder returns the old position in RecyclerView
我有一个 Fragment 和 BottomSheet 行为,其中包含水平 RecyclerView。 RecyclerView通过SnapHelper调整,实现一个页面效果。它看起来像这样:
在Fragment的onCreateView事件中,我设置了Adapter和布局管理器:
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
我设置Adapter后,onCreateViewHolder事件在MyRecyclerAdapter中被触发class对象,后面是onBindViewHolder:
@Override
public MyRecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.fragment_recycler_item, parent, false);
return new MyViewHolder(view, parent);
}
@Override
public void onBindViewHolder(MyRecyclerAdapter.MyViewHolder viewHolder, int position) {
/**I do something using position**/
}
当我第一次创建这个 Fragment 并配置 RecyclerView 时,一切正常,onBindViewHolder returns 正确的位置。但是当我翻转到第一个、第二个等元素 RecyclerView,然后重新创建片段时,出于某种未知原因 onBindViewHolder return 旧的(最后一个)位置,尽管创建了新的 Adapter 和 LineraLayoutManager。
为了清楚起见,我将把它分成几个步骤:
- 正在创建一个片段。
- 正在创建 MyRecyclerAdapter 的对象 class。在RecyclerView.
中设置
- 正在创建 LinearLayoutManager 的对象 class。在RecyclerView.
中设置
- 触发了MyRecyclerAdapter中的onBindViewHolder事件。我得到 position = 0.
- 我滚动到 position = 2 的元素。
- 我确实分离了这个片段,然后立即附加了这个片段。
- 正在创建 MyRecyclerAdapter 的对象 class。在RecyclerView.
中设置
- 正在创建 LinearLayoutManager 的对象 class。在RecyclerView.
中设置
- 触发了MyRecyclerAdapter中的onBindViewHolder事件。我得到 position = 2.
问题:为什么我得到的是旧位置,最重要的是我该如何修复它?
我读到 Android 专门保存旧的 ViewHolder 以更有效地使用内存,但我不需要它。
UPD(解决方案): 在我看来,这是一个临时解决方案(不理想),但它有效。安装 Adapter 和 LayoutManager 后,您需要 运行 smoothScrollToPosition(0)。使用smoothScrollToPosition(0)非常重要,而不是scrollToPosition(0):
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recycler_view.smoothScrollToPosition(0);
UPD.1(最佳解决方案): 只需使用:
recyclerView.setSaveEnabled(false);
是 Android 自动保存旧的 ViewHolder 以更有效地使用内存。
如果你不需要。
然后再次设置适配器或执行 notifyDataSetChanged();
如果您分离并重新附加片段,则只会销毁和重新创建其视图层次结构。恢复滚动位置是 RecyclerView
状态恢复行为的一部分。
如果您希望 RecyclerView
始终从滚动 0 开始,您可以通过禁用该行为来防止它首先保存其滚动状态:
recyclerView.setSaveEnabled(false);
我有一个 Fragment 和 BottomSheet 行为,其中包含水平 RecyclerView。 RecyclerView通过SnapHelper调整,实现一个页面效果。它看起来像这样:
在Fragment的onCreateView事件中,我设置了Adapter和布局管理器:
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
我设置Adapter后,onCreateViewHolder事件在MyRecyclerAdapter中被触发class对象,后面是onBindViewHolder:
@Override
public MyRecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.fragment_recycler_item, parent, false);
return new MyViewHolder(view, parent);
}
@Override
public void onBindViewHolder(MyRecyclerAdapter.MyViewHolder viewHolder, int position) {
/**I do something using position**/
}
当我第一次创建这个 Fragment 并配置 RecyclerView 时,一切正常,onBindViewHolder returns 正确的位置。但是当我翻转到第一个、第二个等元素 RecyclerView,然后重新创建片段时,出于某种未知原因 onBindViewHolder return 旧的(最后一个)位置,尽管创建了新的 Adapter 和 LineraLayoutManager。
为了清楚起见,我将把它分成几个步骤:
- 正在创建一个片段。
- 正在创建 MyRecyclerAdapter 的对象 class。在RecyclerView. 中设置
- 正在创建 LinearLayoutManager 的对象 class。在RecyclerView. 中设置
- 触发了MyRecyclerAdapter中的onBindViewHolder事件。我得到 position = 0.
- 我滚动到 position = 2 的元素。
- 我确实分离了这个片段,然后立即附加了这个片段。
- 正在创建 MyRecyclerAdapter 的对象 class。在RecyclerView. 中设置
- 正在创建 LinearLayoutManager 的对象 class。在RecyclerView. 中设置
- 触发了MyRecyclerAdapter中的onBindViewHolder事件。我得到 position = 2.
问题:为什么我得到的是旧位置,最重要的是我该如何修复它?
我读到 Android 专门保存旧的 ViewHolder 以更有效地使用内存,但我不需要它。
UPD(解决方案): 在我看来,这是一个临时解决方案(不理想),但它有效。安装 Adapter 和 LayoutManager 后,您需要 运行 smoothScrollToPosition(0)。使用smoothScrollToPosition(0)非常重要,而不是scrollToPosition(0):
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recycler_view.smoothScrollToPosition(0);
UPD.1(最佳解决方案): 只需使用:
recyclerView.setSaveEnabled(false);
是 Android 自动保存旧的 ViewHolder 以更有效地使用内存。
如果你不需要。
然后再次设置适配器或执行 notifyDataSetChanged();
如果您分离并重新附加片段,则只会销毁和重新创建其视图层次结构。恢复滚动位置是 RecyclerView
状态恢复行为的一部分。
如果您希望 RecyclerView
始终从滚动 0 开始,您可以通过禁用该行为来防止它首先保存其滚动状态:
recyclerView.setSaveEnabled(false);