对象动画师不删除更新侦听器android [英] Object animator not removing update listener android

查看:140
本文介绍了对象动画师不删除更新侦听器android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

早上好,我有一个场景,这个一半的普通对象动画师不断反复触发,导致堆增长,当然还有内存不足的问题。我已经为彩虹动画制作了这样的静态方法。

Good day.I have an scenario where this half normal object animator keeps firing over and over causing heap grow and ofcourse out of memory issue at some point.Here is how it go. I have made static method for rainbow animation like this.

  public static ObjectAnimator startRainbowAnimation(Context context,
                                                   String textToShow,
                                                   final TextView textViewToAttach) {
    AnimatedColorSpan span = new AnimatedColorSpan(context);
    final SpannableString spannableString = new SpannableString(textToShow);
    String substring = textToShow;
    int start = textToShow.indexOf(substring);
    int end = start + substring.length();
    spannableString.setSpan(span, start, end, 0);

    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(
            span, ANIMATED_COLOR_SPAN_FLOAT_PROPERTY, 0, 100);
    objectAnimator.setEvaluator(new FloatEvaluator());
    objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            System.gc();
            Log.d("Fafasfasfas", "onAnimationUpdate: inside true");
            textViewToAttach.setText(spannableString);
        }
    });
    objectAnimator.setInterpolator(new LinearInterpolator());
    objectAnimator.setDuration(DURATION);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.start();
    return objectAnimator;
}

private static final Property<AnimatedColorSpan, Float> ANIMATED_COLOR_SPAN_FLOAT_PROPERTY
        = new Property<AnimatedColorSpan, Float>(Float.class, "ANIMATED_COLOR_SPAN_FLOAT_PROPERTY") {
    @Override
    public void set(AnimatedColorSpan span, Float value) {
        span.setTranslateXPercentage(value);
    }

    @Override
    public Float get(AnimatedColorSpan span) {
        return span.getTranslateXPercentage();
    }
};

我在回收视图适配器中这样调用此方法

I am calling this method like this inside an recycler view adapter

 @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        ChatModel chatModel = chatModelList.get(position);

        System.gc();

        String messageBody = chatModel.getMessage().replaceAll("userid=" + chatModel.getUserId() + ":" + Constants.TYPE_MESSAGE_ATTACHMENT, "").replaceAll("userid=" + chatModel.getOpponentId() + ":" + Constants.TYPE_MESSAGE_ATTACHMENT, "");
        holder.message.setText(messageBody);
         if (showAsRainbow) {
                if (holder.message.getTag() == null) {
                    objectAnimator = RainbowAnimation.startRainbowAnimation(mContext, messageBody, holder.message);
                    holder.message.setTag(ANIMATED);
                }
            } else {
                objectAnimator.removeAllUpdateListeners();
                objectAnimator.removeAllListeners();
                objectAnimator.end();
                objectAnimator.cancel();
                holder.message.setTag(null);
            }

        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) holder.chatViewBubble.getLayoutParams();
        LinearLayout.LayoutParams deliveryStatusParams = (LinearLayout.LayoutParams) holder.deliveryStatus.getLayoutParams();
        LinearLayout.LayoutParams gifChatViewLayoutParams = (LinearLayout.LayoutParams) holder.imageViewWrapper.getLayoutParams();

        checkForGif(chatModel, holder);

        if (mCurrentUserId.equals(chatModel.getUserId())) {
            layoutParams.gravity = Gravity.RIGHT;
            layoutParams.rightMargin = Dp.toDps(mContext, 16);
            deliveryStatusParams.gravity = Gravity.RIGHT;
            gifChatViewLayoutParams.gravity = Gravity.RIGHT;

            holder.chatViewBubble.setLayoutParams(layoutParams);
            holder.imageView.setLayoutParams(gifChatViewLayoutParams);

            holder.chatViewBubble.setBackground(ContextCompat.getDrawable(mContext, R.drawable.outgoing_message_bg));
            if (chatModel.getDeliveryStatus().equals(Constants.STATUS_DELIVERED)) {
                if (position >= chatModelList.size() - 1) {
                    holder.deliveryStatus.setVisibility(View.VISIBLE);
                } else {
                    holder.deliveryStatus.setVisibility(View.INVISIBLE);
                }
                holder.deliveryStatus.setText(mContext.getString(R.string.sentText));
            } else if (chatModel.getDeliveryStatus().equals(Constants.STATUS_NOT_DELIVERED)) {
                holder.deliveryStatus.setVisibility(View.VISIBLE);
                if (updating) {
                    holder.deliveryStatus.setText(mContext.getString(R.string.sendingNowText) + percentage + " %");
                } else {
                    holder.deliveryStatus.setText(mContext.getString(R.string.sendingNowText));
                }

            }
        } else {
            holder.chatViewBubble.setBackground(ContextCompat.getDrawable(mContext, R.drawable.incoming_message_bg));
            layoutParams.gravity = Gravity.LEFT;
            gifChatViewLayoutParams.gravity = Gravity.LEFT;

            holder.chatViewBubble.setLayoutParams(layoutParams);
            holder.imageView.setLayoutParams(gifChatViewLayoutParams);
            holder.deliveryStatus.setVisibility(View.INVISIBLE);
        }

    }

问题是,如果您注意到 Log.d()仍然触发,即使在objectAnimator上调用了cancle和end之后,是的,我已经检查了cancel和end被调用了,所以我不知道我做错了什么。有人可以帮我吗?

Thi issue is that if you noticed the Log.d() keeps firing even after the cancle and end was called on the objectAnimator and yes i have checked that cancel and end is being called.So i have no clue what i have done wrong.Can anyone please help me?

推荐答案

我看到很多人都在看这个帖子,这意味着他们也有这个问题,所以我以某种方式解决了问题...问题是,即使在使用静态方法的循环内完成此诅咒的ObjectAnimator,每次都创建了对此的新引用。所以您必须执行类似的操作。对象动画师的数组列表,每次调用时将项目添加到数组列表。每当要停止它时,只需循环遍历数组并停止所有对象动画师。这是代码

I see lot's of guys been looking at the post,meaning they got this issue too so i got the solution somehow fixed...Issue is that this damned ObjectAnimator when done inside an loop even with static method,each time is being created new reference to it.So you have to do something like this.Have an array list of object animators,on each call add items to array list.Whenever you want to stop it just simply loop through array and stop all object animators.Here is the code

private ArrayList<ObjectAnimator> objectAnimators = new ArrayList<>();
  public void startRainbowAnimation(Context context,
                                  final String textToShow,
                                  final TextView textViewToAttach) {
    stopCalled = false;
    AnimatedColorSpan span = new AnimatedColorSpan(context);
    final SpannableString spannableString = new SpannableString(textToShow);
    String substring = textToShow;
    int start = textToShow.indexOf(substring);
    int end = start + substring.length();
    spannableString.setSpan(span, start, end, 0);

    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(
            span, animatedColorSpanFloatProperty, 0, 100);
    objectAnimator.setEvaluator(new FloatEvaluator());

    objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            System.gc();
            if (!stopCalled) {
                textViewToAttach.setText(spannableString);
            }
        }
    });
    objectAnimator.setInterpolator(new LinearInterpolator());
    objectAnimator.setDuration(DateUtils.MINUTE_IN_MILLIS * 3);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.start();
    objectAnimators.add(objectAnimator);
}
objectAnimators here is an array list of object animators like this

这是您如何停止所有这些驱动程序来激发无限更新侦听器调用的原因。

And here is how you stop all of them to get ride of infinite update listener call firing.

 public void stopRainbowAnimation() {
    System.gc();
    stopCalled = true;
    if (!objectAnimators.isEmpty()) {
        for (int i = 0; i < objectAnimators.size(); i++) {
            ObjectAnimator eachAnimator = objectAnimators.get(i);
            eachAnimator.setRepeatCount(0);
            eachAnimator.end();
            eachAnimator.cancel();
            eachAnimator.removeAllListeners();
            eachAnimator.removeAllUpdateListeners();
        }
        objectAnimators.clear();
    }
}

希望这会帮助到某人

这篇关于对象动画师不删除更新侦听器android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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