svguerin3
svguerin3

Reputation: 2483

Android - Animating layout using align-parent (Kotlin)

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

Answers (1)

ashakirov
ashakirov

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:

enter image description here

Upvotes: 3

Related Questions