Question:
How to make it look like this when hiding several View-elements adjacent to the LinearLayout:
- View elements fade smoothly at the same time.
- Everything under them smoothly slides up into their place.
And similarly for setVisibility(View.VISIBLE)
.
Tried using animateLayoutChanges="true"
– it doesn't work.
UPD:
animateLayoutChanges="true"
did not work only in ScrollView
, after transferring this attribute to LinearLayout
everything LinearLayout
out.
Answer:
The problem can be solved using the ViewPropertyAnimator . Take for example a LinearLayout
with three elements:
<LinearLayout
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="ru.jollydroid.propertyanimationdisappearance.MainActivity">
<TextView
android:id="@+id/one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000"
android:padding="16dp"
android:text="One"
android:textColor="#00ffff"/>
<TextView
android:id="@+id/two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00ff00"
android:padding="16dp"
android:text="Two"
android:textColor="#ff00ff"/>
<TextView
android:id="@+id/three"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0000ff"
android:padding="16dp"
android:text="Three"
android:textColor="#ffff00"/>
</LinearLayout>
How would we do without animation?
two.setVisibility(View.GONE);
What does it do? Element two
disappears, element three
is moved up by two
.
What kind of animation do we need? First, the element two
smooth decrease in opacity, then the element three
smoothly shifted up to the height of the element two
. So we will write down:
void stepOne() {
two.animate()
.setDuration(500)
.alpha(0)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
stepTwo();
}
});
}
void stepTwo() {
three.animate()
.setDuration(500)
.translationY(-binding.two.getHeight())
.setInterpolator(new AccelerateInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
stepThree();
}
});
}
/*
нужно в конце анимаци вернуть свойства в исходное состояние, но так,
чтобы взаимное расположение осталось неизменным
*/
void stepThree() {
// отключаем лиснеры, на всякий случай, чтобы при следующей анимации неожиданно не сработал
three.animate().setListener(null);
two.animate().setListener(null);
// сводим задачу к предыдущей
two.setVisibility(View.GONE);
// возвращаем свойства в исходное состояние
three.setTranslationY(0);
binding.two.setAlpha(1);
}
When an event stepOne()
must be run.
Whether you need to clean up the effects of the animation in the third step is up to you. If this is a one-time effect, then it is necessary that further work with the interface is not unexpected, because, for example, the three
element will remain offset from its original position. If all the behavior of the interface will be based on animation, then it is not necessary that the appearance of the element two
back can be done in the same way as it disappears.
There was a blog post about this animation: https://android-developers.googleblog.com/2011/05/introducing-viewpropertyanimator.html
Another example of using this same animation is in my article: http://jollydroid.ru/notebook/2016-04-05-Property-Animation-Rotation.html