使用ValueAnimator为LayoutParams制作动画会导致requestLayout()调用不正确

时间:2014-01-08 15:20:50

标签: android android-animation layoutparams

我正在尝试设置特定视图高度的变化。我已经使用Evaluator设置了ValueAnimator,并在动画的每次传递时更新LayoutParams。反过来,这会触发requestLayout()调用。然而,在布局传递完成之前,动画的下一次传递会更新LayoutParams并触发另一个requestLayout()。结果是在LogCat中输出警告以及动画效果不佳。它似乎跳过很多帧。

    ValueAnimator contentHeightAnimator = ValueAnimator.ofObject(new HeightEvaluator(mContentView),
            mContentView.getMeasuredHeight(), (int) (getMeasuredHeight() - (actionBarHeight + destinationY)));
    contentHeightAnimator.setDuration(duration);
    contentHeightAnimator.setInterpolator(mInterpolator);
    contentHeightAnimator.start();

...

private static class HeightEvaluator extends IntEvaluator {

    private View mView;

    public HeightEvaluator(View v) {
        this.mView = v;
    }

    @Override
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int num = (Integer) super.evaluate(fraction, startValue, endValue);
        ViewGroup.LayoutParams params = mView.getLayoutParams();
        params.height = num;
        mView.setLayoutParams(params);
        return num;
    }

}

布局更改动画的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

这是我用来设置分割菜单的动画,以便插入另一个较低级别的菜单

    final int newBottomMargin = (int)(origBottomMargin + halfMargin);
    final int newTopMargin = (int)(origTopMargin + halfMargin);

    splitUp = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            LinearLayout.LayoutParams params =  (LinearLayout.LayoutParams) btnShopWireless.getLayoutParams();
            params.bottomMargin = (int)(newBottomMargin * interpolatedTime);
            btnShopWireless.setLayoutParams(params);
        }
    };

    splitDown = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            LinearLayout.LayoutParams params =  (LinearLayout.LayoutParams) btnShopBundles.getLayoutParams();
            params.topMargin = (int)(newTopMargin * interpolatedTime);
            btnShopBundles.setLayoutParams(params);
        }
    };