首页 文章

在ViewHolder的项目RecyclerView中清除动画

提问于
浏览
2

我正在使用RecyclerView并有一些动画,我在ViewHolder项目中放大了RelativeLayout之一 .

Note: 这不是添加/删除/插入动画 . 它在用户在ViewHolder项目中进行交互时启动 . 因此我不在这里使用ItemAnimator .

动画工作正常,但它会在一些随机的View项中重新出现(最终状态) . 我知道这是由于重复使用的项目,我也在清理动画,但它没有帮助 .

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
    Model model = getModelObject(position);
    ((Model) viewHolder.itemView).showItem(position);   
}

我在showItem中这样做

relativeLayout.clearAnimation();
        relativeLayout.setAnimation(null);

在onViewDetachedFromWindow中

@Override
public void onViewDetachedFromWindow(ViewHolder holder) {
    ((ItemView) holder.itemView).clearAllAnimations();
    super.onViewDetachedFromWindow(holder);

}

ClearAllAnimations

public void clearAllAnimations() {
    for (RelativeLayout layout : layoutArray) {
        optionLayout.clearAnimation();
        optionLayout.setAnimation(null);
    }

这是我如何动画视图

public AnimatorSet onDragStartAnimation(RelativeLayout group[]) {

    AnimatorSet big = new AnimatorSet();
    for (RelativeLayout relativeLayout : group) {
        ObjectAnimator scaleXSmall = ObjectAnimator.ofFloat(relativeLayout, "scaleX", 1.0f, 0.85f);
        ObjectAnimator scaleYSmall = ObjectAnimator.ofFloat(relativeLayout, "scaleY", 1.0f, 0.85f);

        big.playTogether(scaleXSmall, scaleYSmall);
    }

    return big;
}

它不起作用 . RelativeLayout在某个随机视图项中没有重置并出现在scaledup状态 .

Update

我做了一个小实验:在ViewHolder项目中的ImageView上设置alpha动画,就像这样

Animation fadeInAnimation = AnimationUtils.loadAnimation(mContext, R.anim.fadein);
imageView.startAnimation(fadeInAnimation);

并使用了清晰的动画 . imageView.clearAnimation();当下次ViewItem出现在屏幕上时,它工作正常并且ImageView正常 .

但如果我这样做,同样不起作用

alphaAnimator = ObjectAnimator.ofFloat(centerImageView, "alpha", 1.0f, 0.5f);
        alphaAnimator.start();

并清楚这一点

alphaAnimator.removeAllListeners();
        alphaAnimator.cancel();
        alphaAnimator.end();

这没用 . Alpha动画保留在ViewHolder图像项中 .

3 回答

  • 3

    我通过对onViewDetachedFromWindow中的所有动画师进行反向动画来解决它 .

    @Override
    public void onViewDetachedFromWindow(ViewHolder holder) {
        if (holder.getItemViewType() == 1) ((MyItemView) holder.itemView).reverseAllAnimations();
    }
    
  • 0

    我用这种方式解决了这个问题 . 一切正常 .

    GroupsViewHolder - 它是自定义的RecyclerView.ViewHolder

    @Override
        public void onViewAttachedToWindow(GroupsViewHolder holder) {
            super.onViewAttachedToWindow(holder);
            //here add animation
        }
    
        @Override
        public void onViewDetachedFromWindow(GroupsViewHolder holder) {
            //here clear animation
            super.onViewDetachedFromWindow(holder);
        }
    
  • 2

    通过启发来自crymson的回答Crymson's answer我使用View的标记方法,而不是在自定义适配器的复杂逻辑中设置布尔值,我做了一些简单而有用的解决方案 .

    @Override
    public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
        super.onViewDetachedFromWindow(holder);
        if (holder.getItemViewType() == TYPE_AD)
            ((ViewHolderForAd) holder).ivStory.setTag(false);
    }
    
    
    public class ViewHolderForAd extends RecyclerView.ViewHolder {
            private ImageView ivStory;
            TextView tvName;
    
        public ViewHolderForAd(View view) {
            super(view);
            ivStory = (ImageView) view.findViewById(R.id.ivStoryImage);
            tvName = (TextView) view.findViewById(R.id.tvAppName);
            view.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    int pos = getAdapterPosition();
                    if (pos < 0) {
                        pos = (int) v.getTag();
                    }
                    customItemClickListener.onItemClicked(v, pos);
                }
            });
    
           //ivStory.startAnimation(AnimationUtils.loadAnimation(context, R.anim.pulse_story));
            ivStory.setTag(false); //Set default tag false to decrease risk of null
        }
    }
    
     @Override
        public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
    //...Your code...
    if (!(boolean) holder1.ivStory.getTag()) {
         holder1.ivStory.setTag(true);
         holder1.ivStory.startAnimation(AnimationUtils.loadAnimation(context, R.anim.pulse_story));
    }
    //...Your code...//
    }
    

    如果已经在imageView中标记了某些内容(如位置),则可以使用setTag(key,object)而不是setTag(object) . 希望这有助于某人 .

相关问题