【问题标题】:Animating Android ListView header height causes flicker at the end of animation动画Android ListView标题高度会导致动画结束时闪烁
【发布时间】:2015-01-31 13:12:11
【问题描述】:

问题

我正在尝试为 ListView 标题高度设置动画。我可以得到正确的动画,但动画完成后 ListView 闪烁。

尝试失败

  1. 使用AnimationSet.setFillAfter() 更改布局参数。动画效果很好,但是当您开始滚动列表时,标题会跳回原始位置。
  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;

 }

我认为可以通过监听和覆盖ListView的ViewTreeObserver的onPreDraw()onGlobalLayout()事件来避免闪烁。但我不知道如何实现它。

非常感谢任何帮助!

【问题讨论】:

    标签: android android-listview android-animation


    【解决方案1】:

    我选择使用 ValueAnimator 来实现相同的效果,而不是为 ListView 标头设置动画。这是代码:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-12
      • 2011-02-26
      • 2013-01-24
      • 1970-01-01
      • 2023-03-29
      • 2015-04-29
      • 1970-01-01
      • 2012-03-11
      相关资源
      最近更新 更多