Android:使用扩展动画添加视图(无闪烁)

10
我想使用展开动画向视图组添加一个视图,因此添加的视图从非常小的尺寸开始,逐渐占用更多的空间,直到达到其全尺寸(可能在此过程中移动其他视图)。
在尝试了不同的方法后,我想出了以下解决方案。如果这对您有所帮助,请投票支持,或者提供更好的替代方案。我相信一定有更简单的方法来实现这个目标。
如需更多信息,请参阅类似这篇文章这篇文章的帖子。
以下是我添加视图并启动动画的方式:
// Trick: set height to 1 so the view doesn't take its full size at the beginning.
// (0 doesn't work, I don't know why)
container.addView(view, LayoutParams.MATCH_PARENT, 1);
Animation expansion = createExpansion(view);
expansion.setDuration(200);
view.startAnimation(expansion);
createExpansion() 方法:
该方法用于创建一个扩展。
public static Animation createExpansion(View view) {

    return new SizedHeightScaleAnimation(view, 0, 1,
            Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, 0f);
}

最后,是 SizedHeightScaleAnimation 动画类:
/**
 * Like {@link ScaleAnimation} for height scaling that also resizes the view accordingly,
 * so it takes the right amount of space while scaling.
 */
public class SizedHeightScaleAnimation extends ScaleAnimation {

    private float fromHeight;
    private float toHeight;
    private View viewToScale;

    public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY) {
        super(1, 1, fromY, toY);
        init(viewToScale, fromY, toY);
    }

    public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, float pivotX, float pivotY) {
        super(1, 1, fromY, toY, pivotX, pivotY);
        init(viewToScale, fromY, toY);
    }

    public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
        super(1, 1, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);
        init(viewToScale, fromY, toY);
    }

    private void init(View viewToScale, float fromY, float toY) {

        this.viewToScale = viewToScale;
        viewToScale.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        fromHeight = viewToScale.getMeasuredHeight() * fromY;
        toHeight = viewToScale.getMeasuredHeight() * toY;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);

        final int newHeight = (int) (fromHeight * (1 - interpolatedTime) + toHeight * interpolatedTime);

        viewToScale.getLayoutParams().height = newHeight;
        viewToScale.requestLayout();
    }
}

顺便提一下,您可以通过以下方式创建折叠效果:

public static Animation createCollapse(View view) {

    return new SizedHeightScaleAnimation(view, 1, 0,
            Animation.RELATIVE_TO_SELF, 0f,
            Animation.RELATIVE_TO_SELF, 0f);
}

当您使用它时,可能希望在动画完成后从其父视图中删除该视图:
Animation collapse = createCollapse(view);
collapse.setDuration(200);

collapse.setAnimationListener(new AnimationListener() {
    @Override
    public void onAnimationEnd(Animation animation) {
        final ViewGroup parent = (ViewGroup) view.getParent();
        parent.removeView(view);
    }

    ... other overrides ...
});

view.startAnimation(collapse);
1个回答

6
这可能会更简单一些:
public void expand(final View view) {
    view.getLayoutParams().height = 0;

    Animation a = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t)
        {
            view.getLayoutParams().height = (int)(mTargetHeight * interpolatedTime);
            view.requestLayout();
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    a.setDuration(1000);
    view.startAnimation(a);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接