使用 ViewCompat 时出现 StackOverflowError
StackOverflowError when using ViewCompat
我正在使用 viewCompat
来兼容我的动画以降低 api (10)。
但是当我在模拟器上部署它时,我得到 WhosebugError
这是我的代码:
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.WhosebugError
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.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.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.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.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.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.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.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.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimat
如您所见,错误返回到代码的 onAnimationEnd
部分。
你在 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();
如果我们查看源代码,我们会看到兼容 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;
}
所以在内部兼容动画中使用附加到您的视图的动画器缓存。现在让我们 return 处理您的情况。您有观点 floatingActionButton
。你为此打电话 ViewCompat.animate()
。然后在内部实现中创建 ViewPropertyAnimatorCompat
并将其分配给您的视图。然后你 set
'ing listener for it.
动画完成后,您再次调用 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();
总之需要在onAnimationEnd
回调
中添加.setListener(null)
构建动画
我正在使用 viewCompat
来兼容我的动画以降低 api (10)。
但是当我在模拟器上部署它时,我得到 WhosebugError
这是我的代码:
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.WhosebugError
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.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.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.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.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.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.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.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.onAnimationEnd(MainActivity.java:305)
at android.support.v4.view.ViewPropertyAnimatorCompat$BaseViewPropertyAnimat
如您所见,错误返回到代码的 onAnimationEnd
部分。
你在 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();
如果我们查看源代码,我们会看到兼容 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;
}
所以在内部兼容动画中使用附加到您的视图的动画器缓存。现在让我们 return 处理您的情况。您有观点 floatingActionButton
。你为此打电话 ViewCompat.animate()
。然后在内部实现中创建 ViewPropertyAnimatorCompat
并将其分配给您的视图。然后你 set
'ing listener for it.
动画完成后,您再次调用 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();
总之需要在onAnimationEnd
回调
.setListener(null)
构建动画