>问题
我正在尝试对列表视图标题高度进行动画处理。我可以正确获取动画,但是在动画完成后,列表视图闪烁。
尝试并失败
- 在不更改布局参数的情况下使用
AnimationSet.setFillAfter()
。动画工作正常,但是当您开始滚动列表时,标题会跳回到原始位置。 - 将
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;
}
我认为可以通过侦听和覆盖列表视图的 ViewTreeObserver onPreDraw()
或onGlobalLayout()
的事件来避免闪烁。但我不知道我该如何实现它。
任何帮助都非常感谢!
我没有对 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;
}