我正在构建一个基于RecyclerView的组件,允许用户通过拖放重新排序项目。一旦我在DragListener端,我需要它在适配器中的位置,以便执行正确的移动,但我只能访问视图。所以这是我在适配器视图绑定中所做的事情:
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
Track track = mArray.get(position);
viewHolder.itemView.setTag(R.string.TAG_ITEM_POSITION, position);
}
你觉得这样对吗?因为如果我移动这样的项目:
public void move(int from, int to){
Track track = mArray.remove(from);
mArray.add(to, track);
notifyItemMoved(from, to);
}
然后位置标记不再正确,如果我notifyDataSetChanged(),我失去了花哨的动画。有什么建议吗?
不,这是错的。首先,在该方法返回后,您无法引用传递给onBindViewHolder的位置。当物品的位置发生变化时(由于物品移动等),RecyclerView不会重新绑定视图。
相反,您可以使用ViewHolder#getPosition()
,它将返回更新的位置。
如果你解决了这个问题,你的移动代码应该工作并提供漂亮的动画。
调用notifyDataSetChanged
会阻止预测动画,所以尽可能避免使用它。有关详细信息,请参阅documentation。
编辑(来自评论):从外部获取位置,从recyclerview获取子视图持有者,然后从vh获取位置。有关详细信息,请参阅RecyclerView api
有一种方法可以用notifyDataSetChanged()
来保存精美的动画
GridLayoutManager
方法制作自己的qazxsw poi,返回qazxsw poi;supportsPredictiveItemAnimations()
true
方法。它应该返回真正独特的值,而不是mAdapter.setHasStableIds(true)
的直接函数。像getItemId()
之类的东西在我的情况下工作得非常好 - 仅使用position
添加,移除和移动项目的美丽动画
1)你将使用mItems.get(position).hashCode()
或notifyDataSetChanged()
代替notifyItemInserted(position);
进行动画制作。 2)你可以手动修复你的问题 - 使用
notifyItemRemoved(position);
你应该将你的方法移动到notifyDataSetChanged()
,然后public void move(int from, int to){
Track track = mArray.remove(from);
mArray.add(to, track);
notifyItemMoved(from, to);
ViewHolder fromHolder = (ViewHolder) mRecyclerView.findViewHolderForPosition(from);
ViewHolder toHolder = (ViewHolder) mRecyclerView.findViewHolderForPosition(to);
Tag fromTag = fromHolder.itemView.getTag();
fromHolder.itemView.setTag(toHolder.itemView.getTag());
toHolder.itemView.setTag(fromTag);
}
正常工作。
我可以通过将其添加到我的列表项的外部元素来维护触摸动画
OnCreateViewHolder