2

I have three activities A, B and C, and use shared element transitions between A and B and between B and C.

A -> B works fine, and then using back button or finishAfterTransition smoothly reverses the transition from B back to A.

B -> C works fine too, going back from C to B is also smooth.

However A -> B -> C -> B -> A is the problem. The C -> B transition is smooth, but then the B back to A transition is 'forgotten' and is just an instant jump without a smooth transition.

Why is B -> A different after having gone B -> C -> B ? Update - this is only happening under API30 (using a Nexus 9 emulation). When I use a Nexus 9 with API28, everything works as expected!

When starting the activities I am using:

val options = ActivityOptions.makeSceneTransitionAnimation(this, transition_name)
startActivity(intent, options.toBundle())

I had a theory that the problem was occurring in B, when calling C it was changing the enterTransition, sharedElementEnterTranstion, exitTransition, sharedElementExitTranstion, returnTransition, sharedElementReturnTranstion, reenterTransition, sharedElementReenterTranstion attributes of B, and hence not transitioning back to A. However I've saved and logged all these and the object details don't seem to be different in either scenario.

Any help gratefully received, thanks.

I've mocked this up in a very simple three activity project to demonstrate the problem:

First screen XML:

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/testtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:onClick="secondActivity"
        android:text="Go to second screen"
        android:transitionName="transition_name"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Second screen XML:

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <TextView
        android:id="@+id/testtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Welcome to the second activity"
        android:transitionName="transition_name"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.147" />

    <TextView
        android:id="@+id/testtext2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:onClick="thirdActivity"
        android:text="Go to third screen"
        android:transitionName="transition_name2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.996"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.466" />

</androidx.constraintlayout.widget.ConstraintLayout>

Third screen XML:

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ThirdActivity">

    <TextView
        android:id="@+id/testtext2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:transitionName="transition_name2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.845" />

</androidx.constraintlayout.widget.ConstraintLayout>

Main activity:

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Pair
import android.view.View

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun secondActivity(view: View) {

        val intent = Intent(this, SecondActivity::class.java)

        val view: View = findViewById(R.id.testtext)
        val pair = Pair.create(view, "transition_name")

        val options = ActivityOptions.makeSceneTransitionAnimation(this, pair)
        startActivity(intent, options.toBundle())
    }
}

Second activity:

import android.app.ActivityOptions
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.transition.Fade
import android.transition.Transition
import android.util.Log
import android.util.Pair
import android.view.View

class SecondActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
    }

    fun thirdActivity(view: View) {

            val intent = Intent(this, ThirdActivity::class.java)
            val view: View = findViewById(R.id.testtext2)
            val pair = Pair.create(view, "transition_name2")
            val options = ActivityOptions.makeSceneTransitionAnimation(this, pair)

            startActivity(intent, options.toBundle())
    }

    override fun onBackPressed() {
        super.onBackPressed()
        supportFinishAfterTransition()
    }
}

Third activity:

import android.os.Bundle

class ThirdActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_third)
    }

}
Matthew
  • 31
  • 5
  • Found that this is a duplicate of https://stackoverflow.com/questions/59261601/shared-element-transition-not-working-in-android-10q-while-returning-to-called/62834726#62834726 and is also logged on the Android bugs list https://issuetracker.google.com/issues/158553240 – Matthew May 25 '21 at 09:01

0 Answers0