动画相对布局宽度更改

时间:2015-06-26 07:05:51

标签: android animation

尝试做一个简单的动画,以便缩放相对布局的宽度。我设法使用这段代码完成了它,但即使持续时间为5000毫秒,动画也很快完成。我看不出中间结果。有什么建议吗?

RelativeLayout baseLayer;
RelativeLayout fillLayer;
public void animate(int duration){
    Animation a = new Animation()
    {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t)
        {
            fillLayer.getLayoutParams().width = (int)(baseLayer.getLayoutParams().width * interpolatedTime);
            fillLayer.requestLayout();
        }

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

    a.setDuration(duration);
    a.setInterpolator(new LinearInterpolator());
    fillLayer.startAnimation(a);
}

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。问题是我从OnStart()调用动画方法。现在我从onWindowFocusChanged()调用它。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    testBar.animate(2000,0.8);
}

RelativeLayout baseLayer;
RelativeLayout fillLayer;
public void animate(int duration,float fillPercentage){

    final int targetWidth = (int)(baseLayer.getMeasuredWidth() * fillPercentage);        

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

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

    a.setDuration(duration);
    a.setInterpolator(new LinearInterpolator());
    fillLayer.startAnimation(a);
}

在整个过程中,我从其他帖子中找到了另一种做同样工作的方法。但同样需要从onWindowFocusChanged()调用该方法。

ValueAnimator.ofObject(new WidthEvaluator(fillLayer), fillLayer.getLayoutParams().width, targetWidth).setDuration(2000).start();

class WidthEvaluator extends IntEvaluator {

   private View v;
   public WidthEvaluator(View v) {
     this.v = v;
   }

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

[更新解决方案]

接下来,我已将自定义视图添加到ListView中,然后问题又重新开始。 ListView应该在视图获得实际大小之前做好准备。所以动画是无法完成的,因为getMeasuredWidth()总是返回0(这是从头开始的问题)。

所以我所做的就是在OnCreate()中使用了这段代码片段。

    ViewTreeObserver vto = listBars.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {       
            if (!HackClass.GlobalDrawnFlag) {                     
                adapter.notifyDataSetChanged();
                HackClass.GlobalDrawnFlag = true;
            }
        }
    }); 

这是我的列表适配器类

if (item.getMeasuredWidth==0)
    HackClass.GlobalDrawnFlag = false;
else 
    HackClass.GlobalDrawnFlag = true;

这种方法显然解决了我所有的问题。不过那是一个很好的解决方案吗欢迎任何其他建议。