Я пытаюсь реализовать анимацию слайдов вверх и вниз, что-то вроде этого:
анимация баннера материала gif (взято из поведение баннера материала ).
Допустим, у меня есть следующий макет (упрощенно):
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
// View to animate
<LinearLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
// some views
</LinearLayout>
<Button
android:id="@+id/toggle_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Toggle View" />
// other views
</LinearLayout>
Сначала, чтобы анимировать вид контейнера, я попытался использовать анимацию раскрытия / свертывания:
void collapse(final View view) {
final int initialHeight = view.getMeasuredHeight();
Animation animation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
view.setVisibility(View.GONE);
} else {
view.getLayoutParams().height =
initialHeight - (int) (initialHeight * interpolatedTime);
view.requestLayout();
}
}
};
animation.setInterpolator(new DecelerateInterpolator());
animation.setDuration(1000);
view.startAnimation(animation);
}
void expand(final View view) {
view.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = view.getMeasuredHeight();
view.getLayoutParams().height = 0;
view.setVisibility(View.VISIBLE);
Animation animation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
view.getLayoutParams().height =
interpolatedTime == 1 ? ViewGroup.LayoutParams.WRAP_CONTENT : (int) (
targetHeight * interpolatedTime);
view.requestLayout();
}
};
animation.setInterpolator(new DecelerateInterpolator());
animation.setDuration(1000);
view.startAnimation(animation);
}
Но это не похоже на то, что мне нужно. Он просто изменяет размер представления до тех пор, пока не исчезнет (и выглядит уродливо, особенно если этот вид содержит изображение): развернуть / свернуть анимированную демонстрацию .
Затем я попытался использовать TranslateAnimation
:
void slideUp(final View view) {
final int initialHeight = view.getMeasuredHeight();
Animation animation = new TranslateAnimation(0, 0, 0, -initialHeight) {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
if (interpolatedTime == 1) {
view.setVisibility(View.GONE);
}
}
};
animation.setInterpolator(new DecelerateInterpolator());
animation.setDuration(1000);
view.startAnimation(animation);
}
private void slideDown(View view) {
view.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = view.getMeasuredHeight();
view.setY(-targetHeight);
view.setVisibility(View.VISIBLE);
Animation animation = new TranslateAnimation(0, 0, 0, targetHeight);
animation.setInterpolator(new DecelerateInterpolator());
animation.setDuration(1000);
animation.setFillAfter(true);
view.startAnimation(animation);
}
Эта анимация перемещает весь вид вместо изменения его размера и выглядит почти хорошо. Но другие виды (которые окружают контейнер) не перемещаются с анимацией, пока не будет вызван view.setVisibility(...)
. А также после анимации slide in
анимация slide out
ведет себя странно: демонстрация слайдов анимации .
Я знаю, что могу анимировать другие виды вместе с этим контейнером, но что, если у меня их много, это не вариант. Должно быть какое-то решение, и я потратил некоторое время на его решение, но теперь я застрял с ним.
Как мне добиться такой же анимации, как показано на Google?
Любая помощь приветствуется. Спасибо.