布局更改动画(滑动高度)(范例)
Zas12357386
・5 分钟阅读
概述
我看到很多以幻灯片方式打开的动画,通常,这是要更改的视图的实际布局,然而,如果您只是改变高度,它将只是在闪烁。我给你们展示两种方法来实现这个动画。
ValueAnimation
第一种方法是使用ValueAnimation
(可以在AnimatorSet
中使用),这个动画会改变设置属性的值,并沿着抛物线(或者任何你专门设置进插值器的线方程),然后转到它的每个点,然后让你创建一个方程,基于该行上的动画在哪个位置。
//view we want to animate
final View messageView = view.findViewById(R.id.message_section);
//set the values we want to animate between and how long it takes
//to run
ValueAnimator slideAnimator = ValueAnimator
. ofInt(currentHeight, newHeight)
. setDuration(300);
//we want to manually handle how each tick is handled so add a
//listener
slideAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//get the value the interpolator is at
Integer value = (Integer) animation.getAnimatedValue();
//I'm going to set the layout's height 1:1 to the tick
messageView.getLayoutParams().height = value.intValue();
//force all layouts to see which ones are affected by
//this layouts height change
messageView.requestLayout();
}
});
//create a new animationset
AnimatorSet set = new AnimatorSet();
//since this is the only animation we are going to run we just use
//play
set.play(slideAnimator);
//this is how you set the parabola which controls acceleration
set.setInterpolator(new AccelerateDecelerateInterpolator());
//start the animation
set.start();
自定义动画效果
另外一个更为极端的解决方案,就是创建一个扩展Animation,它似乎不总是按你想要的方式工作,这比上面的ValueAnimator
要灵活得多,而且工作几乎完全一样,你可以使构造函数采用新的高度和旧的高度。这也使用了插值器,所以,你仍然可以设置一个自定义方程,下面是一个基本示例:
public class SlideAnimation extends Animation {
int mFromHeight;
int mToHeight;
View mView;
public SlideAnimation(View view, int fromHeight, int toHeight) {
this.mView = view;
this.mFromHeight = fromHeight;
this.mToHeight = toHeight;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
int newHeight;
if (mView.getHeight()!= mToHeight) {
newHeight = (int) (mFromHeight + ((mToHeight - mFromHeight) * interpolatedTime));
mView.getLayoutParams().height = newHeight;
mView.requestLayout();
}
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
以上几乎完全相同,但是,你必须在某处使用它,所以,看起来像这样,
View messageView = view.findViewById(R.id.message_section);
Animation animation = new SlideAnimation(messageView, currentHeight, newHeight);
//this interpolator only speeds up as it keeps going
animation.setInterpolator(new AccelerateInterpolator());
animation.setDuration(300);
messageView.setAnimation(animation);
messageView.startAnimation(animation);
结束语
这两种方法都可以获得相同的结果,并且可以构建。注意,它并非总是在所有地方工作,当我制作这个自定义动画类时,当我在一个抽屉中使用它时它不能工作,但是,ValueAnimator 可以.
</p>