1

I am trying to understand how ConstraintLayout, ConstraintSet and TransitionManager work in Android development. For that I made the following tiny application and then I have a question for any expert in the field that may happen to read this.

First, here is the XML (activity_main.xml):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/   apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

Then here is the code (MainActivity.kt)http:

package world.software.tryapp

import android...... // imports lines.

class MainActivity : AppCompatActivity() {
    private var constrLayout: ConstraintLayout? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        constrLayout = findViewById(R.id.main)
        animateView()
    }


    fun animateView() {
        val mainFrameID = resources.getIdentifier("main","id",packageName)
        val constrSet = ConstraintSet(); val otherConstrSet = ConstraintSet()

        val appLabel = TextView(this)
        appLabel.id = View.generateViewId()
        val appLabelID = appLabel.id
        appLabel.text = "ANDROID&LINUX"

        constrLayout?.addView(appLabel)

        constrSet.clone(constrLayout)
        constrSet.connect(appLabelID, ConstraintSet.LEFT, mainFrameID, ConstraintSet.LEFT)
        constrSet.connect(appLabelID, ConstraintSet.TOP, mainFrameID, ConstraintSet.TOP)
        constrSet.applyTo(constrLayout)

        otherConstrSet.clone(constrLayout)
        otherConstrSet.clear(appLabelID, ConstraintSet.LEFT)
        otherConstrSet.clear(appLabelID, ConstraintSet.TOP)
        otherConstrSet.connect(appLabelID, ConstraintSet.RIGHT, mainFrameID, ConstraintSet.RIGHT)
        otherConstrSet.connect(appLabelID, ConstraintSet.BOTTOM, mainFrameID, ConstraintSet.BOTTOM)

        val autoTransition = AutoTransition()
        autoTransition.setDuration(5000)
        TransitionManager.beginDelayedTransition(constrLayout, autoTransition)
        otherConstrSet.applyTo(constrLayout);

// The next 4 lines have the same effects as the previous 4 lines when used instead.
//        val transition = ChangeBounds()
//        transition.setDuration(5000L)
//        TransitionManager.go(Scene(constrLayout), transition)
//        otherConstrSet.applyTo(constrLayout);
    }
}

Finally this is my question:

When executed this app displays directly the label "ANDROID&LINUX" at the bottom right of the screen.

This is not what I expect. In fact what I want (and expect) is:

First to see the label at the top left of the screen, then see it moving taking five seconds to the bottom right.

Why am I not getting the expected result ? Can anyone explain what the problem is and if possible let me know what I need to modify in the code ?

Michel
  • 10,303
  • 17
  • 82
  • 179
  • 2
    Delayed transition works by calculating layout differences and right now it's discarded entirely because your view was not laid out yet. Try wrapping your transition code with `constrLayout.post{ ... }` so it gets executed after first layout phase. – Pawel May 01 '22 at 11:31
  • I tried and got something working based on your suggestion. Thanks a lot. – Michel May 01 '22 at 15:15

0 Answers0