我使用viewCompat
将我的动画兼容到较低的api(10)。
但是当我在模拟器上部署它时,我得到StackOverflowError
这是我的代码:
private void fabFadeIn(){
if (floatingActionButton.getVisibility() == View.GONE) {
floatingActionButton.setVisibility(View.VISIBLE);
ViewCompat.setAlpha(floatingActionButton, 0f);
ViewCompat.setScaleX(floatingActionButton, 0f);
ViewCompat.setScaleY(floatingActionButton, 0f);
ViewCompat.animate(floatingActionButton)
.alpha(1)
.scaleX(1)
.scaleY(1)
.setDuration(300)
.setInterpolator(new OvershootInterpolator())
.setListener(new ViewPropertyAnimatorListener() {
@Override
public void onAnimationStart(View view) {
}
@Override
public void onAnimationEnd(View view) {
ViewCompat.animate(floatingActionButton).setInterpolator(new LinearOutSlowInInterpolator()).start();
}
@Override
public void onAnimationCancel(View view) {
}
})
.start();
}
}
这是错误:
java.lang.StackOverflowError
at java.lang.Thread.currentThread(Thread.java:557)
at java.lang.ThreadLocal.get(ThreadLocal.java:59)
at android.view.ViewRoot.getRunQueue(ViewRoot.java:3340)
at android.view.View.removeCallbacks(View.java:5407)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.removeStartMessage(ViewPropertyAnimatorCompat.java:341)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:268)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.startAnimation(ViewPropertyAnimatorCompat.java:308)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimatorCompatImpl.start(ViewPropertyAnimatorCompat.java:269)
at android.support.v4.view.ViewPropertyAnimatorCompat.start(ViewPropertyAnimatorCompat.java:1249)
at com.test.app.activities.MainActivity$2.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimat
正如您所看到的,错误可以追溯到代码的onAnimationEnd
部分。
答案 0 :(得分:3)
如果我们转到消息来源,我们会看到兼容animate
方法的实现之一是:
@Override
public ViewPropertyAnimatorCompat animate(View view) {
if (mViewPropertyAnimatorCompatMap == null) {
mViewPropertyAnimatorCompatMap = new WeakHashMap<>();
}
ViewPropertyAnimatorCompat vpa = mViewPropertyAnimatorCompatMap.get(view);
if (vpa == null) {
vpa = new ViewPropertyAnimatorCompat(view);
mViewPropertyAnimatorCompatMap.put(view, vpa);
}
return vpa;
}
因此,在内部兼容动画中,使用附加到视图的动画制作缓存。现在让我们回到你的案子。您有查看floatingActionButton
。你打电话给ViewCompat.animate()
。然后在内部实现中创建ViewPropertyAnimatorCompat
并将其分配给您的视图。然后你set
为听众做准备。
动画播完后,您再次致电animate
,而不是创建新的ViewPropertyAnimatorCompat
(似乎是逻辑上的),您收到了之前创建的ViewPropertyAnimatorCompat
与您指定的听众。因此,你有无限循环。
要解决此问题,您需要编写如下内容:
ViewCompat.animate(floatingActionButton)
.alpha(1)
.scaleX(1)
.scaleY(1)
.setDuration(300)
.setInterpolator(new OvershootInterpolator())
.setListener(new ViewPropertyAnimatorListener() {
@Override
public void onAnimationStart(View view) {
}
@Override
public void onAnimationEnd(View view) {
ViewCompat.animate(floatingActionButton).setInterpolator(new LinearOutSlowInInterpolator()).setListener(null).start();
}
@Override
public void onAnimationCancel(View view) {
}
})
.start();
简而言之,您需要在.setListener(null)
回调
onAnimationEnd
到建筑动画
答案 1 :(得分:2)
您在ViewCompat.animate(floatingActionButton)
内拨打ViewCompat.animate(floatingActionButton)
,以便获得无限循环:
ViewCompat.animate(floatingActionButton)
....
@Override
public void onAnimationEnd(View view) {
ViewCompat.animate(floatingActionButton).setInterpolator(new LinearOutSlowInInterpolator()).start();
}
@Override
public void onAnimationCancel(View view) {
}
})
.start();