2014-12-03 137 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; 
}