Android: добавить вид с расширенной анимацией (не мигая)
Я хочу добавить представление в группу представлений, используя расширяющуюся анимацию, поэтому добавленное представление начинается очень маленьким и занимает все больше и больше места, пока не достигнет своего полного размера (возможно, перемещая другие представления в процессе).
Попробовав разные подходы, я нашел решение, приведенное ниже. Проголосуйте, если вам это поможет, или, пожалуйста, опубликуйте лучшую альтернативу. Я уверен, что должен быть более простой способ сделать это.
Для получения дополнительной информации смотрите сообщения, какэтот а такжеэтот.
Вот как я добавляю вид и запускаю анимацию:
// Trick: set height to 1 so the view doesn't take its full size at the beginning.
// (0 doesn't work, I don't know why)
container.addView(view, LayoutParams.MATCH_PARENT, 1);
Animation expansion = createExpansion(view);
expansion.setDuration(200);
view.startAnimation(expansion);
createExpansion()
метод:
public static Animation createExpansion(View view) {
return new SizedHeightScaleAnimation(view, 0, 1,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f);
}
И наконецSizedHeightScaleAnimation
урок анимации:
/**
* Like {@link ScaleAnimation} for height scaling that also resizes the view accordingly,
* so it takes the right amount of space while scaling.
*/
public class SizedHeightScaleAnimation extends ScaleAnimation {
private float fromHeight;
private float toHeight;
private View viewToScale;
public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY) {
super(1, 1, fromY, toY);
init(viewToScale, fromY, toY);
}
public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, float pivotX, float pivotY) {
super(1, 1, fromY, toY, pivotX, pivotY);
init(viewToScale, fromY, toY);
}
public SizedHeightScaleAnimation(View viewToScale, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
super(1, 1, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);
init(viewToScale, fromY, toY);
}
private void init(View viewToScale, float fromY, float toY) {
this.viewToScale = viewToScale;
viewToScale.measure(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
fromHeight = viewToScale.getMeasuredHeight() * fromY;
toHeight = viewToScale.getMeasuredHeight() * toY;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
final int newHeight = (int) (fromHeight * (1 - interpolatedTime) + toHeight * interpolatedTime);
viewToScale.getLayoutParams().height = newHeight;
viewToScale.requestLayout();
}
}
Кстати, вы можете создать эффект коллапса следующим образом:
public static Animation createCollapse(View view) {
return new SizedHeightScaleAnimation(view, 1, 0,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0f);
}
Когда вы используете его, вы, вероятно, захотите удалить представление из его родителя, когда анимация будет завершена:
Animation collapse = createCollapse(view);
collapse.setDuration(200);
collapse.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
final ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
... other overrides ...
});
view.startAnimation(collapse);