美好的一天。我有一个场景,这个半正常的对象动画师不停地一遍又一遍地开火,导致堆积增长,并且在某些时候出现内存问题。这就是它的发展方向。我已经为这样的彩虹动画制作了静态方法。
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();
}
};
我在回收站视图适配器
中调用此方法 @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()
即使在对象andAmatmat上调用cancle和end之后仍然继续射击,是的我已经检查了取消并且正在调用end。所以我不知道我有什么做错了。任何人都可以帮帮我吗?
答案 0 :(得分:1)
我看到很多人都在看帖子,这意味着他们也得到了这个问题,所以我得到了解决方案以某种方式修复...问题就是这个该死的ObjectAnimator在循环内完成,即使用静态方法,每次都是为它创建新的引用。所以你必须做类似这样的事情。有一个对象动画的数组列表,在每次调用时将项添加到数组列表。无论何时你想要停止它只是简单地遍历数组并停止所有对象动画师。这是代码
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
以下是如何阻止所有这些操作以获得无限更新侦听器调用的操作。
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();
}
}
希望这会有所帮助