Android 在ViewHolder'中清除动画;s项目回收视图
我正在使用RecyclerView并制作了一些动画,其中我在ViewHolder项中缩放了一个RelativeLayout 注意:这不是添加/删除/插入动画。当用户在ViewHolder项中进行交互时,它将启动。因此,我这里不使用ItemAnimator 动画工作正常,但它会在某个随机视图项中重新出现(最终状态)。我知道这是由于重复使用的项目,我清除动画太多,但它没有帮助Android 在ViewHolder'中清除动画;s项目回收视图,android,animation,android-recyclerview,Android,Animation,Android Recyclerview,我正在使用RecyclerView并制作了一些动画,其中我在ViewHolder项中缩放了一个RelativeLayout 注意:这不是添加/删除/插入动画。当用户在ViewHolder项中进行交互时,它将启动。因此,我这里不使用ItemAnimator 动画工作正常,但它会在某个随机视图项中重新出现(最终状态)。我知道这是由于重复使用的项目,我清除动画太多,但它没有帮助 @Override public void onBindViewHolder(ViewHolder viewHolder,
@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);
}
透明化
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未重置并以缩放状态出现在某些随机视图项中
更新
我做了一个小实验:在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图像项中。我通过在onViewDetachedFromWindow中对所有动画师进行反向动画来解决这个问题
@Override
public void onViewDetachedFromWindow(ViewHolder holder) {
if (holder.getItemViewType() == 1) ((MyItemView) holder.itemView).reverseAllAnimations();
}
从Crimson的回答中得到启发,我使用视图的标记方法,而不是在自定义适配器的复杂逻辑中设置一个布尔值,从而制定了一个简单而有用的解决方案
@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...//
}
@覆盖
ViewDetachedFromWindow上的公共无效(RecyclerView.ViewHolder){
super.onview从窗口分离(支架);
if(holder.getItemViewType()==TYPE\u AD)
((ViewHolderForAd)holder.ivStory.setTag(false);
}
公共类ViewHolderForAd扩展了RecyclerView.ViewHolder{
私家侦探小说;
文本视图tvName;
公共视图持有者文件夹(视图){
超级(视图);
ivStory=(ImageView)view.findViewById(R.id.ivStoryImage);
tvName=(TextView)view.findViewById(R.id.tvAppName);
view.setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
int pos=getAdapterPosition();
如果(位置<0){
pos=(int)v.getTag();
}
customItemClickListener.onItemClicked(v,pos);
}
});
//ivStory.startAnimation(AnimationUtils.loadAnimation(context,R.anim.pulse_story));
setTag(false);//将默认标记设置为false以降低null的风险
}
}
@凌驾
BindViewHolder上的公共无效(RecyclerView.ViewHolder ViewHolder,int i){
//…你的代码。。。
if(!(布尔)holder1.ivStory.getTag()){
holder1.ivStory.setTag(true);
holder1.ivStory.startAnimation(AnimationUtils.loadAnimation(context,R.anim.pulse_story));
}
//…你的代码//
}
如果已经在imageView中标记了某些内容(如位置),则可以使用setTag(键,对象)而不是setTag(对象)。希望这对某人有所帮助。我用这种方法解决了这个问题。一切正常 GroupsViewHolder-它是自定义的RecyclerView.ViewHolder
你在哪里调用此代码?尝试清除中的动画我是否需要扩展RecyclerView来执行此操作?抱歉,我的意思是,你可以从适配器中覆盖它IDN无助。。。请参阅更新什么是ReverseLanimations();?我找不到这样的方法。视图中没有方法ReverseLanimations()。
@Override
public void onViewAttachedToWindow(GroupsViewHolder holder) {
super.onViewAttachedToWindow(holder);
//here add animation
}
@Override
public void onViewDetachedFromWindow(GroupsViewHolder holder) {
//here clear animation
super.onViewDetachedFromWindow(holder);
}