使用ViewCompat时出现StackOverflowError

时间:2016-09-13 06:52:46

标签: android android-animation android-appcompat viewpropertyanimator

我使用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部分。

2 个答案:

答案 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();