在ViewHolder的项目RecyclerView中清除动画

时间:2016-01-17 09:29:35

标签: android animation android-recyclerview

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

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

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

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

我在showItem

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

}

在onViewDetachedFromWindow

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

ClearAllAnimations

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;
}

这里我是如何为视图设置动画

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

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

更新

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

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

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

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

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

要清除这个

angular.module('starter', ['ionic', 'ngCordova', 'ngImgCrop', 'ngFileUpload'])

    .controller("ExampleController", ['$scope', '$cordovaCamera', 'Upload', '$timeout', function ($scope, $cordovaCamera, Upload, $timeout) {

        $scope.takePhoto = function () {
            var options = {
                quality: 100,
                destinationType: Camera.DestinationType.DATA_URL,
                sourceType: Camera.PictureSourceType.CAMERA,
                allowEdit: true,
                encodingType: Camera.EncodingType.JPEG,
                targetWidth: 300,
                targetHeight: 300,
                popoverOptions: CameraPopoverOptions,
                saveToPhotoAlbum: true
            };
            $cordovaCamera.getPicture(options).then(function (imageData) {
                $scope.imgURI = "data:image/jpeg;base64," + imageData;
            }, function (err) {
                console.log(err);
                alert(err);
            });
        }    
        $scope.choosePhoto = function () {
            var options = {
                quality: 100,
                destinationType: Camera.DestinationType.DATA_URL,
                sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
                allowEdit: true,
                encodingType: Camera.EncodingType.JPEG,
                targetWidth: 300,
                targetHeight: 300,
                popoverOptions: CameraPopoverOptions,
                saveToPhotoAlbum: false
            };

            $cordovaCamera.getPicture(options).then(function (imageData) {
                $scope.imgURI = "data:image/jpeg;base64," + imageData;
                $scope.myImage = $scope.imgURI;
            }, function (err) {
                console.log(err);
                alert(err);
            });
        }
       $scope.myCroppedImage = '';
       $scope.upload = function (dataUrl) {
           Upload.upload({
                url: 'http://192.168.1.20/wcf/OCRService.svc',
                file: "data:image/jpeg;base64," + dataUrl

            }).then(function (response) {
                $timeout(function () {
                    $scope.result = response.data;
                    console.log(response.data);
                    alert(response.data);
                });
            }, function (response) {
                if (response.status > 0) $scope.errorMsg = response.status
                    + ': ' + response.data;
                alert(response.status);
            });
       }
   }]);

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

3 个答案:

答案 0 :(得分:3)

我通过对onViewDetachedFromWindow中的所有动画师进行反向动画解决了这个问题。

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

答案 1 :(得分:2)

我以这种方式解决了这个问题。一切正常。

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 :(得分:0)

通过启发来自Crymson's answer的crymson的回答,我使用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)。希望这有助于某人。