0

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

我知道如何为事物设置动画,但在这种情况下,我希望它不对视图进行任何布局,因为我的动画将发生在 LinearLayout 内,并且不会超过它的大小。

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

在此处输入图像描述

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

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

4

2 回答 2

0

这完全取决于您所针对的 API 级别,如果您只针对 >3.0,那么ObjectAnimator 和 ValueAnimator或更好的ViewPropertyAnimator是您最好的朋友,它们可以让您做一些简单的事情,例如“在增加的同时移动这个 100dp 的 X 值宽度乘以两倍,在 300 毫秒内”。

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

做你想做的事,应该是这样的:

myImageView.scaleXBy(FACTOR_NEEDED_FOR_NEW_WIDTH);

仅此而已。

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

于 2013-10-28T21:37:49.213 回答
0

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

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

边距动画类:

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);
    }
}
于 2013-10-29T01:05:00.980 回答