Reputation: 2483
I am needing to animate a layout from bottom to the top of the screen when the user taps on an EditText within that layout. Here is my code for doing this:
myEditText.setOnFocusChangeListener() { _, focused ->
if (focused) {
val animation = object: Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
val params = myLayout.getLayoutParams() as RelativeLayout.LayoutParams
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE)
myLayout.setLayoutParams(params)
}
}
animation.duration = 1000
myEditText.startAnimation(animation)
}
}
When I tap on the EditText, the "myLayout" properly goes to the top of the screen. However, two issues:
1) There is no animation, it just jumps to the top. I am wanting it to "slide" up to the top.
2) More importantly, the views that are set to be "below" and relative to the myLayout do not go up with it. I know those are set properly, since when I add in the top alignment in the XML, they go up with it. But programatically it seems they stay down below the screen, still hidden.
I tried a different approach using ObjectAnimator, manually moving all the views up:
val anims = AnimatorSet();
val anim1 = ObjectAnimator.ofFloat(myLayout, View.TRANSLATION_Y, -1000f)
val anim2 = ObjectAnimator.ofFloat(layoutBelow, View.TRANSLATION_Y, -1000f)
val anim3 = ObjectAnimator.ofFloat(layoutBelowBelow, View.TRANSLATION_Y, -1000f)
anims.playTogether(anim1, anim2, anim3)
anims.start()
Doing that makes the animation work, but the views below "myLayout" are still invisible! I'm curious if it makes a difference that they are off-screen initially (?)
Thoughts on what I may be missing? If there's a better way to handle this, I'm open to different approaches as well.
Upvotes: 0
Views: 815
Reputation: 12360
This kind of animations can be done via Transition API
which is now available in androix
package.
Here is example where Button
is centerVertical
in RelativeLayout
. TextView
aligned to be below Button
. After button click I remove centerVertical
rule and add alignParentTop
rule to Button
. All animations can be done in almost 1 line.
import androidx.transition.AutoTransition;
import androidx.transition.TransitionManager;
....
@Override
protected void onCreate(Bundle savedInstanceState) {
....
View button = findViewById(R.id.button);
button.setOnClickListener(btn -> {
animate(btn);
});
}
private void animate(View button) {
RelativeLayout parent = findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) button.getLayoutParams();
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
lp.removeRule(RelativeLayout.CENTER_VERTICAL);
AutoTransition transition = new AutoTransition();
transition.setDuration(2000);
TransitionManager.beginDelayedTransition(parent, transition);
button.setLayoutParams(lp);
}
layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Button" />
<TextView
android:id="@+id/bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button"
android:layout_centerHorizontal="true"
android:text="bottom text" />
</RelativeLayout>
Result:
Upvotes: 3