我有一个包含3个LinearLayout的片段。默认情况下,第一个权重属性为1。
每个LinearLayout都有OnClickListener
触发2个动画:
我的问题是有时动画没有完全完成。
以下是OnClickListener触发的代码:
private void launchAnimation(final LinearLayout llToExpand) {
ViewWeightAnimationWrapper animationWrapper = new ViewWeightAnimationWrapper(llToExpand);
ObjectAnimator anim = ObjectAnimator.ofFloat(animationWrapper,
"weight",
animationWrapper.getWeight(),
1f);
anim.setDuration(1000);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Log.d("Anim1", "onAnimationEnd: Anim1 have ended");
}
@Override
public void onAnimationCancel(Animator animation) {
Log.d("Anim1", "onAnimationCancel: Anim1 have been canceled.");
}
});
ViewWeightAnimationWrapper animationWrapper2 = new ViewWeightAnimationWrapper(mLlCurrentlyOpened);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(animationWrapper2,
"weight",
animationWrapper2.getWeight(),
0f);
anim2.setDuration(1000);
anim2.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Log.d("Anim2", "onAnimationEnd: Anim2 have ended");
mLlCurrentlyOpened = llToExpand;
}
@Override
public void onAnimationCancel(Animator animation) {
Log.d("Anim2", "onAnimationCancel: Anim2 have been canceled.");
}
});
anim.start();
anim2.start();
}
以下是我的ViewWeightAnimationWrapper的代码:
public class ViewWeightAnimationWrapper {
private View view;
public ViewWeightAnimationWrapper(View view) {
if (view.getLayoutParams() instanceof LinearLayout.LayoutParams) {
this.view = view;
} else {
throw new IllegalArgumentException("The view should be a LinearLayout");
}
}
public void setWeight(float weight) {
Log.i(String.valueOf(view.getId()), "setWeight: " + weight);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
params.weight = weight;
view.requestLayout();
}
public float getWeight() {
return ((LinearLayout.LayoutParams) view.getLayoutParams()).weight;
}
以下是动画未结束时的日志:
I/2131755212: setWeight: 0.5
I/2131755207: setWeight: 0.5
I/2131755212: setWeight: 0.5251222
I/2131755207: setWeight: 0.47487777
I/2131755212: setWeight: 0.55174345
I/2131755207: setWeight: 0.44825655
D/Anim1: onAnimationCancel: Anim1 have been canceled.
D/Anim1: onAnimationEnd: Anim1 have ended
D/Anim2: onAnimationCancel: Anim2 have been canceled.
D/Anim2: onAnimationEnd: Anim2 have ended
我不知道为什么每次都不取消我的动画。
我如何知道取消动画的内容?是否有可能在取消动画时强制完成动画?
答案 0 :(得分:0)
我还没有找到动画被取消原因的原因。 在文档中,他们说当在同一个对象上触发相同的动画时动画被取消,这不是我的情况。
但是,我找到了一个解决方法here,它给了我预期的结果。
我已经通过自定义动画替换了ObjectAnimator:
/**
* Launch the expand animation on the LinearLayout in parameter and launch the folding animation
* on the currently opened LinearLayout.
* @param llToExpand LinearLayout that we want to expand.
*/
private void launchAnimation(final LinearLayout llToExpand) {
// Create the and assign the animations
ExpandAnimation expand = new ExpandAnimation(llToExpand, 0, 1);
expand.setDuration(500);
ExpandAnimation fold = new ExpandAnimation(mLlCurrentlyOpened, 1, 0);
fold.setDuration(500);
// Start the animations
llToExpand.startAnimation(expand);
mLlCurrentlyOpened.startAnimation(fold);
// Switch the currently opened LinearLayout for the next time
mLlCurrentlyOpened = llToExpand;
}
这是我的ExpandAnimation:
public class ExpandAnimation extends Animation {
private float mStartWeight;
private final float mEndWeight;
private final LinearLayout mContent;
public ExpandAnimation(LinearLayout content, float startWeight,
float endWeight) {
mStartWeight = startWeight;
mEndWeight = endWeight;
mContent = content;
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContent
.getLayoutParams();
mStartWeight = lp.weight;
lp.weight = (mStartWeight + ((mEndWeight - mStartWeight) * interpolatedTime));
mContent.setLayoutParams(lp);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
答案 1 :(得分:0)
我只是遇到了可能是相同的问题。查看ObjectAnimator源,它持有对动画目标的WeakReference。以我为例,我使用的是创建专门用于执行动画的专用对象,事实证明,弱引用是 only 引用。因此,有时在动画过程中会取消引用它。 ObjectAnimator可以“干净”地处理它,只需取消动画即可。