2014-12-03 2 views
1

ПроблемыОживляющего Android высоты заголовка ListView вызывает мерцание в конце анимации

Я пытаюсь анимировать высоту заголовка ListView. Я могу получить анимацию правильно, но после того, как анимация завершится, Flickers ListView.

Пробовал и не

  1. Использование AnimationSet.setFillAfter()без изменения Params макета. Анимация отлично работает, но когда вы начинаете прокрутку списка, заголовок возвращается к исходной позиции.
  2. Использовать AnimationSet.setFillAfter()с новыми параметрами макета, применяемыми на onAnimationEnd(). После окончания анимации заголовок переходит на удвоенную требуемую высоту (анимированная высота плюс высота, заданная в параметрах макета). Когда вы начинаете прокрутку списка, заголовок привязывается к требуемой высоте.

Код

if (mSearchAdapter.getCount() > 0 && mListView.getChildAt(0) == mHeaderPlaceholder) { 
     Log.i(TAG, "Animating list view to make room for info bar"); 
     AnimationSet slideAnimation = new AnimationSet(true); 
     TranslateAnimation translate = new TranslateAnimation(0, 0, 0, newHeight); 
     translate.setDuration(mInfoBarAnimationDuration); 
     translate.setInterpolator(new DecelerateInterpolator()); 
     slideAnimation.addAnimation(translate); 
     slideAnimation.setAnimationListener(new Animation.AnimationListener() { 

       @Override 
       public void onAnimationStart(Animation animation) { 
        isAnimatingViewTransition = true; 
       } 
       @Override 
       public void onAnimationEnd(Animation animation) { 
        isAnimatingViewTransition = false; 
        final AbsListView.LayoutParams layoutParams = (AbsListView.LayoutParams) mHeaderPlaceholder.getLayoutParams(); 
        layoutParams.height = newHeight; 
        mHeaderPlaceholder.setLayoutParams(layoutParams); 
       } 
       @Override 
       public void onAnimationRepeat(Animation animation) { 

       } 

     }); 

     mListView.startAnimation(slideAnimation); 
} else { 

     Log.i(TAG, "Adjusting list view header to make room for info bar"); 
     mHeaderPlaceholder.getLayoutParams().height = newHeight; 

} 

Я думаю, что мерцание можно избежать путем прослушивания и опрокинув события onPreDraw() или onGlobalLayout() из ViewTreeObserver в ListView. Но я точно не знаю, как я могу это достичь.

Любая помощь очень ценится!

ответ

2

Вместо анимации заголовка ListView я решил использовать ValueAnimator для достижения такого же эффекта. Вот код:

if (mSearchAdapter.getCount() > 0 && mListView.getChildAt(0) == mHeaderPlaceholder) { 
      ValueAnimator mSlideListViewAnimator = ObjectAnimator.ofInt(from, to); 
      mSlideListViewAnimator.setDuration(mInfoBarAnimationDuration); 
      mSlideListViewAnimator.setInterpolator(new DecelerateInterpolator()); 
      mSlideListViewAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator animation) { 
        Integer animatedYValue= (Integer) animation.getAnimatedValue(); 
        final AbsListView.LayoutParams layoutParams = (AbsListView.LayoutParams) mHeaderPlaceholder.getLayoutParams(); 
        layoutParams.height = animatedYValue; 
        mHeaderPlaceholder.requestLayout(); 
       } 
      }); 
      mSlideListViewAnimator.addListener(new AnimatorListenerAdapter() { 
       @Override 
       public void onAnimationStart(Animator animation) { 
        isAnimatingViewTransition = true; 
       } 

       @Override 
       public void onAnimationEnd(Animator animation) { 
        isAnimatingViewTransition = false; 
       } 
      }); 
      mSlideListViewAnimator.start(); 
} else { 
      Log.i(TAG, "Adjusting list view header to make room for info bar"); 
      mHeaderPlaceholder.getLayoutParams().height = newHeight; 
} 
Смежные вопросы