私はウェブサイトからの画像を表示するアプリを開発中です。画像はすべて高さが異なり、表示されるビュー(ビューア)も同様です。RecyclerViewのデータセットを置き換える際の問題
フィルタを適用すると、前のデータセット(したがって現在表示されているもの)が直接削除されます。アダプタ。これが起こったことがアダプタに通知されます
final int removedSize = items.size();
items.clear();
notifyItemRangeRemoved(0, removedSize);
これにより、古いアイテムが画面からアニメーション表示されます。アニメーションが終了したら、新しいデータセットを追加します。
RecyclerView attachedView;
attachedView.getItemAnimator().isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() { // Add a listener to listen when the new items should be added
@Override
public void onAnimationsFinished() {
attachedView.postDelayed(new Runnable() {
@Override
public void run() {
addPhotosList(objects);
notifyItemRangeChanged(0, objects.size());
loading = false;
attachedView.requestLayout();
}
},700);
}
});
これは、追加されたアイテムをアニメーション化します。 奇妙なことは、RecyclerViewが、すべてのアイテムを描画するときに、RecyclerViewがViewHolderの新しいディメンションを考慮しないように、ときどきRecyclerViewの内部にギャップが生じることです。さらに、アイテムのいくつかは、文字通りお互いの上に置かれ、好きなときは常に前景に点滅します。正しい位置に置かれたアイテムの上にあるアイテムは、そのギャップの内側に配置されるアイテムです。彼らはギャップに戻ることはありませんが、手動で項目セットを調べるとき、私は彼らがそこにいるはずであることに気付きました。
RecyclerViewはSwipeRefreshLayoutビューの子ですが、問題ではないと思います。
私はRecyclerViewに設定したパラメータの一部:
recents.setLayoutManager(layoutManager);
recents.setHasFixedSize(false);
recents.setItemViewCacheSize(100);
レイアウトファイル内
android:animationCache="false"
android:scrollingCache="false"
私が間違って何をしているのですか?
私はすでにすべてのアニメーションが終了していることを確認するために、わずか0.7秒の遅延を追加しましたが、それはあまり役に立たないようです。
ItemAnimator:
@Override
public boolean animateAdd(RecyclerView.ViewHolder viewHolder) {
if (viewHolder.getItemViewType() != -8) { // ImageAdapter.ViewType.EMPTY = -8;
if (viewHolder.getLayoutPosition() > lastAddAnimatedItem) {
lastAddAnimatedItem++;
runEnterAnimation((ImageListView) viewHolder, viewHolder.getLayoutPosition());
return false;
}
}
lastAddAnimatedItem = -6;
dispatchAddFinished(viewHolder);
return false;
}
@Override
public boolean animateRemove(RecyclerView.ViewHolder viewHolder) {
if (viewHolder.getItemViewType() != -8) { // ImageAdapter.ViewType.EMPTY = -8;
if (viewHolder.getLayoutPosition() > lastRemoveAnimatedItem) {
lastRemoveAnimatedItem++;
runExitAnimation((ImageListView) viewHolder, viewHolder.getLayoutPosition());
return false;
}
}
lastRemoveAnimatedItem = -6;
dispatchRemoveFinished(viewHolder);
return false;
}
private void runEnterAnimation(final ImageListView holder, int position) {
final int screenHeight = Utils.getScreenHeight(holder.itemView.getContext());
holder.itemView.setTranslationY(screenHeight + holder.itemView.getHeight());
holder.itemView.animate()
.translationY(0)
.setStartDelay(150 + (20 * (position)))
.setInterpolator(new DecelerateInterpolator(3.f))
.setDuration(700)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
dispatchAddFinished(holder);
}
})
.start();
}
private void runExitAnimation(final ImageListView holder, int position) {
final int screenHeight = Utils.getScreenHeight(holder.itemView.getContext());
holder.itemView.setTranslationY(0);
holder.itemView.animate()
.translationY(-screenHeight - holder.itemView.getHeight())
.setStartDelay(Math.abs(20 * (position)))
.setInterpolator(new DecelerateInterpolator(3.f))
.setDuration(700)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
dispatchRemoveFinished(holder);
}
})
.start();
}
EDIT:
画面上で最後の目に見えるアイテムが間違った場所に配置された後、それは、最初項目と思われます。