RecyclerView适配器notifyDataSetChanged停止花哨的动画

问题描述 投票:29回答:5

我正在构建一个基于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(),我失去了花哨的动画。有什么建议吗?

android adapter android-recyclerview
5个回答
5
投票

不,这是错的。首先,在该方法返回后,您无法引用传递给onBindViewHolder的位置。当物品的位置发生变化时(由于物品移动等),RecyclerView不会重新绑定视图。

相反,您可以使用ViewHolder#getPosition(),它将返回更新的位置。

如果你解决了这个问题,你的移动代码应该工作并提供漂亮的动画。

调用notifyDataSetChanged会阻止预测动画,所以尽可能避免使用它。有关详细信息,请参阅documentation

编辑(来自评论):从外部获取位置,从recyclerview获取子视图持有者,然后从vh获取位置。有关详细信息,请参阅RecyclerView api


108
投票

有一种方法可以用notifyDataSetChanged()来保存精美的动画

  1. 你需要使用覆盖GridLayoutManager方法制作自己的qazxsw poi,返回qazxsw poi;
  2. 你需要supportsPredictiveItemAnimations()
  3. 我发现棘手的部分是你需要覆盖适配器的true方法。它应该返回真正独特的值,而不是mAdapter.setHasStableIds(true)的直接函数。像getItemId()之类的东西

在我的情况下工作得非常好 - 仅使用position添加,移除和移动项目的美丽动画


3
投票

1)你将使用mItems.get(position).hashCode()notifyDataSetChanged()代替notifyItemInserted(position);进行动画制作。 2)你可以手动修复你的问题 - 使用

notifyItemRemoved(position);

0
投票

你应该将你的方法移动到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); } 正常工作。


0
投票

我可以通过将其添加到我的列表项的外部元素来维护触摸动画

OnCreateViewHolder
© www.soinside.com 2019 - 2024. All rights reserved.