在Android中制作矩形动画的最佳方法

时间:2013-10-28 21:27:32

标签: android animation view menuitem

我想为填充了一种不透明颜色的矩形设置动画。我将动画的属性是翻译和活动菜单项的宽度。

我知道如何制作动画,但在这种情况下,我希望它在视图上不做任何布局,因为我的动画将出现在LinearLayout中,并且它不会超过它的大小。

布局顶部的蓝线是我将要制作的动画。它将水平向左和向右,同时改变它的宽度,以便它适合所选的菜单项。

enter image description here

我通常在边距上使用动画,但它会消耗大量处理来重新计算布局过程中的边界。

有关如何做到这一点的任何建议吗?

2 个答案:

答案 0 :(得分:0)

这完全取决于您所定位的API级别,如果您只定位> 3.0然后ObjectAnimator and ValueAnimator或更好的ViewPropertyAnimator是您最好的朋友,他们会让您做一些简单的事情,例如“移动此100dp的X值,同时将宽度增加两倍,在300ms内。”

如果您的目标是较低的API级别,请查看NineOldAndroids,这会将该功能带到所有Android版本。

要做你想做的事情,那就是:

myImageView.scaleXBy(FACTOR_NEEDED_FOR_NEW_WIDTH);

这就是它的全部。

作为旁注:看起来您可能正在尝试复制ViewPager的指标,在​​这种情况下,您应该使用实际指标。

答案 1 :(得分:0)

我必须为视图的边距和宽度设置动画,因为我没有出路,因为我使用的是Android版> = 8。

这是我的两个类可以做到这一点:

MarginAnimation类:

public class MarginAnimation extends Animation{// implements AnimationListener{
    public static String TAG = "MarginAnimation";

    protected View animatingView;

    protected int fromMarginLeft = 0;
    protected int fromMarginTop = 0;

    protected int toMarginLeft = 0;
    protected int toMarginTop = 0;

    protected LayoutParams layoutParam;

    public MarginAnimation(View v, int toMarginLeft, int toMarginTop) {
        this.toMarginLeft = toMarginLeft;
        this.toMarginTop = toMarginTop;

        this.animatingView = v;

        // Save layout param
        layoutParam = (LayoutParams) animatingView.getLayoutParams();

        // Save current margins as initial state
        saveCurrent();

        // Set the listner to be self object
//      setAnimationListener(this);
    }

    public MarginAnimation(View v, int fromMarginLeft, int toMarginLeft, int fromMarginTop, int toMarginTop) {
        this.fromMarginLeft = fromMarginLeft;
        this.toMarginLeft = toMarginLeft;

        this.fromMarginTop = fromMarginTop;
        this.toMarginTop = toMarginTop;

        this.animatingView = v;

        // Save layout param
        layoutParam = (LayoutParams) animatingView.getLayoutParams();

        // Set the listner to be self object
//      setAnimationListener(this);
    }

    protected void saveCurrent(){
        fromMarginLeft = layoutParam.leftMargin;
        fromMarginTop  = layoutParam.topMargin;
    }

    long lastTime = 0;

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
//      long thisTime = System.nanoTime();

//      if(lastTime != 0)
//          Log.e(TAG, ((thisTime - lastTime) / 1000) + "delta Anim.");

//      lastTime = thisTime;

        layoutParam.leftMargin = (int)(fromMarginLeft + (toMarginLeft - fromMarginLeft) * interpolatedTime);
        layoutParam.topMargin = (int)(fromMarginTop + (toMarginTop- fromMarginTop) * interpolatedTime);
        animatingView.setLayoutParams(layoutParam);
    }

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

MarginAndWidthAnimation类:

public class MarginAndWidthAnimation extends MarginAnimation{
    public static String TAG = "MarginAndWidthAnimation";

    int toWidth;
    int fromWidth;

    public MarginAndWidthAnimation(View v, int toMarginLeft, int toMarginTop, int toWidth) {
        super(v, toMarginLeft,toMarginTop);

        this.toWidth = toWidth;

//      Log.i(TAG, "++F: "+this.fromWidth+" T: "+this.toWidth);
    }

    protected void saveCurrent(){
        super.saveCurrent();
//      fromWidth = animatingView.getWidth();
        fromWidth = layoutParam.width;
//      Log.i(TAG, "F: "+fromWidth+" T: "+toWidth);
    }

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

        layoutParam.width = (int)(fromWidth + (toWidth - fromWidth) * interpolatedTime);
//      Log.i(TAG, "F: "+fromWidth+" T: "+toWidth+" S: "+layoutParam.width);
        super.applyTransformation(interpolatedTime, t);
    }
}