ユーザーがドラッグアンドドロップでアイテムの順序を変更できるように、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);
}
その後、位置タグが正しくなくなり、DataSetChanged()に通知すると、派手なアニメーションが失われます。なにか提案を ?
いいえ、間違っています。まず、cannotメソッドが戻った後にonBindViewHolderに渡された位置への参照です。 RecyclerViewは、(アイテムの移動などにより)位置が変更されてもビューを再バインドしません。
代わりに、ViewHolder#getPosition()
を使用して、更新された位置を返すことができます。
これを修正すると、ムーブコードが機能し、ニースのアニメーションが提供されるはずです。
notifyDataSetChanged
を呼び出すと、予測アニメーションが妨げられるため、可能な限り避けてください。詳細については、 documentation を参照してください。
編集(コメントから):外部から位置を取得するには、recyclerviewから子ビューホルダーを取得し、vhから位置を取得します。詳細については、RecyclerView APIをご覧ください
notifyDataSetChanged()
だけで派手なアニメーションを保持する方法があります
GridLayoutManager
を返すsupportsPredictiveItemAnimations()
メソッドをオーバーライドして、独自のtrue
を作成する必要があります。
mAdapter.setHasStableIds(true)
する必要があります
私が扱いにくいと感じるのは、アダプターのgetItemId()
メソッドをオーバーライドする必要があるということです。 position
の直接関数ではなく、真に一意の値を返す必要があります。 mItems.get(position).hashCode()
のようなもの
私の場合は完璧に機能しました-notifyDataSetChanged()
のみを使用してアイテムを追加、削除、移動するための美しいアニメーション
1)アニメーションには、notifyItemInserted(position);
の代わりにnotifyItemRemoved(position);
またはnotifyDataSetChanged()
を使用します。 2)問題を手動で修正することができます-を使用して
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
に移動すると、notifyItemRemoved(index)
が適切に機能します。
これをリストアイテムの外側の要素に追加することで、タッチアニメーションを維持できます。
<View
Android:foreground="?android:attr/selectableItemBackground"
...>