2014-12-03 135 views
1

問題結束動畫效果的Android的ListView頭高度產生閃爍的動畫

我試圖動畫的ListView頭高度。我可以正確地獲得動畫,但動畫完成後,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()或ListView控件的ViewTreeObserver的onGlobalLayout()避免。但我不知道我能如何實現它。

任何幫助非常感謝!

回答

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; 
}