我想为一个填充了一种不透明颜色的矩形设置动画。我将设置动画的属性是翻译和活动菜单项的宽度。
我知道如何为事物设置动画,但在这种情况下,我希望它不对视图进行任何布局,因为我的动画将发生在 LinearLayout 内,并且不会超过它的大小。
我的布局顶部的蓝线是我将要制作动画的内容。它将水平向左和向右移动,同时改变它的宽度,使其适合所选的菜单项。
我通常在边距上处理动画,但它会消耗大量处理来重新计算布局过程的边界。
关于如何做到这一点的任何建议?
这完全取决于您所针对的 API 级别,如果您只针对 >3.0,那么ObjectAnimator 和 ValueAnimator或更好的ViewPropertyAnimator是您最好的朋友,它们可以让您做一些简单的事情,例如“在增加的同时移动这个 100dp 的 X 值宽度乘以两倍,在 300 毫秒内”。
如果您的目标是较低的 API 级别,请查看NineOldAndroids,它将该功能带到所有版本的 Android。
做你想做的事,应该是这样的:
myImageView.scaleXBy(FACTOR_NEEDED_FOR_NEW_WIDTH);
仅此而已。
作为旁注:看起来您可能正在尝试复制ViewPager的指标,在这种情况下,您应该使用实际指标。
我不得不为视图的边距和宽度设置动画,因为没有出路,因为我使用的是 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);
}
}