0

Я использую viewCompat для совместимости моей анимации с нижним api (10).StackOverflowError при использовании ViewCompat

Но когда я раскрываю это на эмуляторе я получаю 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 раздел кода.

ответ

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 (кажется logicaly) вы получили ранее созданный 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 обратного вызова

+0

Спасибо, человек, ты этого заслужил :) – MAY3AM

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(); 
+0

Но когда я использую 'Animator' вместо 'ViewCompat' все работает нормально! Каково ваше решение, я хочу показать, что 'Interpolator' в конце анимации? – MAY3AM

Смежные вопросы