即使ItemAnimator.canReuseUpdatedViewHolder()返回true,仍会调用OnCreateViewHolder [英] OnCreateViewHolder is still called even if ItemAnimator.canReuseUpdatedViewHolder() returns true

查看:240
本文介绍了即使ItemAnimator.canReuseUpdatedViewHolder()返回true,仍会调用OnCreateViewHolder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的RecyclerView构建一个更改动画。我已经覆盖 canReuseUpdatedViewHolder()以返回 true ,以便保留上一个视图。我在 animateChange()中启动动画,并在结束时立即调用 dispatchAnimationFinished()。参数 oldHolder newHolder animateChange()。

I'm building a change animation for my RecyclerView. I've overriden canReuseUpdatedViewHolder() to return true in order to retain the previous viewholder. I start the animation in animateChange() and call dispatchAnimationFinished() as soon as it ends. Params oldHolder and newHolder are the same instance in animateChange().

然后,一旦动画开始,就会为列表中的每个孩子调用RecyclerView的 onBindViewHolder()。令人惊讶的是,仅对于动画项目,在 onCreateViewHolder()中生成了一个新的ViewHolder,正如我所理解的那样,这是不正确的行为。对于每个其他孩子,旧的ViewHolder绑定在 onBindViewHolder()

Then, as soon as the animation starts, RecyclerView's onBindViewHolder() is called for every child in the list. Surprisingly, only for the animated item a new ViewHolder is spawned in onCreateViewHolder() which as I've understood is not the correct behavior. For every other child the old ViewHolder is bound in onBindViewHolder().

作为附注,<$ c在动画结束之前,很快就会调用$ c> onBindViewHolder()。即使在动画结束后调用 dispatchAnimationFinished(holder)

As a side note, onBindViewHolder() is called too soon, before the animation is finished. Even if dispatchAnimationFinished(holder) is called after the animation is finished.

这是ItemAnimator子类。

Here's the ItemAnimator subclass.

public class CustomItemAnimator extends DefaultItemAnimator {


    @Override
    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
        return true;
    }

    @Override
    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) {
        return true;
    }

    @Override
    public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
        CustomHolder holder = (CustomHolder) newHolder;
        CustomView customView = holder.customView;
        Animator animator = customView.revealAnimation();
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                dispatchAnimationFinished(holder);
            }
        });
        animator.start();
        return false;
    }
}

这里是自定义视图动画代码:

and here's the custom view animation code:

CustomView.java

public Animator revealAnimation() {
    return circularRevealView(visibleView, hiddenView);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private Animator circularRevealView(View visibleView, View invisibleView) {

    // get the center for the clipping circle
    int cx = visibleView.getWidth() / 2;
    int cy = visibleView.getHeight() / 2;

    // get the final radius for the clipping circle
    float finalRadius = (float) Math.hypot(cx, cy);

    // create the animator for this view (the start radius is zero)
    Animator anim =
            ViewAnimationUtils.createCircularReveal(invisibleView, cx, cy, 0, finalRadius);

    visibleView.setVisibility(INVISIBLE);
    invisibleView.setVisibility(View.VISIBLE);

    // return the animation for later use
    return anim;
}

谢谢。

推荐答案

animateChange(...)在notifyDataSetChanged()之后调用,这意味着onBindViewHolder()在animateChange(...)之前。并且holder的状态已经改变。可能是你可以做到这一点

animateChange(...) is called after notifyDataSetChanged(),it means that onBindViewHolder() goes before animateChange(...).and the state of holder has already changed.maybe you can do it this

animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                visibleView.setVisibility(INVISIBLE);
                invisibleView.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                dispatchAnimationFinished(holder);
            }
        });

这篇关于即使ItemAnimator.canReuseUpdatedViewHolder()返回true,仍会调用OnCreateViewHolder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆