【发布时间】:2020-05-30 00:31:49
【问题描述】:
我有一个 Fragment,其 BottomSheet 行为包含一个水平 RecyclerView。 RecyclerView 通过SnapHelper 调整,实现页面效果。它看起来像这样:
在Fragment的onCreateView事件中,我设置了Adapter和LayoutManager:
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
我设置Adapter后,MyRecyclerAdapter类对象中触发onCreateViewHolder事件,接着是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 返回正确的位置。但是当我翻转到第一个、第二个等元素 RecyclerView,然后重新创建片段时,由于某种未知原因 onBindViewHolder 返回旧的(最后一个)位置,虽然新的 Adapter 和 LineraLayoutManager 已创建。
为了清楚起见,我将其分解为几个步骤:
- 创建一个片段。
- 创建MyRecyclerAdapter 类的对象。在RecyclerView中设置它。
- 创建LinearLayoutManager 类的对象。在RecyclerView中设置它。
- MyRecyclerAdapter中的onBindViewHolder 事件被触发。我得到 position = 0。
- 我滚动到 position = 2 的元素。
- 我确实分离了这个片段,然后立即附加这个片段。
- 创建MyRecyclerAdapter 类的对象。在RecyclerView中设置它。
- 创建LinearLayoutManager 类的对象。在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 android-fragments android-recyclerview android-viewholder