我使用StaggeredGridLayoutManager
布局Cardviews
,其中每张卡片都有一个按钮,可以展开和收缩卡片以显示不同的信息。这些卡片在屏幕上垂直排列成两列。这些卡由RealmObject
支持,我使用RealmRecyclerViewAdapter
将它们放在回收站视图中,但我不认为这是问题所在。
当我点击一个导致onBindViewHolder()
被调用的按钮时,我的卡片偶尔会在列之间交换位置。只有相邻列中的卡交换,我可以通过将列数增加到三或四并观察行为来显示这一点。通过将列数更改为一个卡停止交换。当卡片互相交换时有一个很好的动画,但是如果我关闭动画(recyclerView.setItemAnimator(null)
),那么卡片在没有动画的情况下仍然可以交换。
卡片只在调用onBindViewHolder()
时交换位置,并且经常发生这种情况显而易见但是我无法复制功能,它似乎是随机发生的。
以下是一些代码:
显示RecyclerView
:
public class DeviceCardListFragment extends Fragment {
private RecyclerView recyclerView;
private RealmResults<Bank> deviceList;
public int locationId = 0;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.card_list_fragment, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
//Turn off the blinking animation when the Realm Refreshes
RecyclerView.ItemAnimator animator = recyclerView.getItemAnimator();
if (animator instanceof SimpleItemAnimator) {
((SimpleItemAnimator)animator).setSupportsChangeAnimations(false);
}
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
manager.setGapStrategy(GAP_HANDLING_NONE);
recyclerView.setLayoutManager(manager);
recyclerView.setAdapter(new StaggeredDeviceAdapter(getContext(), deviceList));
recyclerView.setItemViewCacheSize(40);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
StaggeredDeviceAdapter
:
public class StaggeredDeviceAdapter extends RealmRecyclerViewAdapter<Bank, StaggeredDeviceViewHolder> {
private RealmResults<Bank> devices;
private Context context;
public StaggeredDeviceAdapter(Context context, RealmResults<Bank> list) {
super(list, true);
this.devices = list;
this.context = context;
}
@Override
public StaggeredDeviceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(context).inflate(R.layout.device_card, null);
//setHasStableIds(true);
StaggeredDeviceViewHolder holder = new StaggeredDeviceViewHolder(layoutView);
return holder;
}
@Override
public void onBindViewHolder(StaggeredDeviceViewHolder holder, int position) {
holder.setValues(devices.get(position), context);
}
}
StaggeredDeviceViewHolder
:
我已经将我的实际视图配置拉出到另一个类中,以获得可重用性,但是我认为其中的任何内容都不重要。
public class StaggeredDeviceViewHolder extends RecyclerView.ViewHolder {
private View view;
DeviceCardHolder holder;
public StaggeredDeviceViewHolder(View view) {
super(view);
holder = new DeviceCardHolder(view, false);
//holder.initialise();
this.view = view;
}
//Called from outside the class
//Sets all of the fields to whatever values we want
public void setValues(Bank bank, Context context) {
holder.initialise();
holder.setValues(bank, context);
}
}
如果您需要我的任何其他信息,请与我们联系。
编辑: 添加领域信息
deviceList = realm.where(Bank.class).equalTo("locationSection",location).findAllSorted("locationID");
这些字段都没有在代码中被更改,实际上它们甚至没有setter。
因为领域是排序的,并且卡只沿水平轴交换,所以我认为问题出在StaggeredGridLayoutManager
而不是Realm。
编辑: 通过额外的测试,我能够可靠地复制问题。
我正在使用StaggeredGridLayoutManager
因为我的卡可以改变大小。这可以通过按下卡上的按钮来完成。将卡扩展并返回其原始大小不会导致onBindViewHolder()
被调用。在其中一张卡更改大小后调用onBindViewHolder()
时,大小正在更改交换列的卡片下面的卡片。这些卡每次都不会交换,但我会说这种情况大约有80%的时间都会发生。只有直接位于我操纵交换位置的卡片下方。
这让我觉得StaggeredGridLayoutManager
对于卡片改变大小时索引的位置感到困惑,可能有关于我缺少的索引的设置....
编辑: 我遇到的问题基本上与此question中列出的问题相同:
......但它没有答案