Reputation: 29454
Recently I started playing with the Transition APIs and there is one thing I can not grasp.
Assume I have two scenes (screenshots attached):
Now, when I click on TRANSIT button, I transfer either from 1st scene to 2nd, or from 2nd to 1st, depending on which scene was shown last. When I transfer from 1st scene to 2nd, everything works as expected: the big blue square is moved to the screen's centre (via changeBounds
transition) and the green square is being slide in to the screen from the screen's top edge (via the slide
) transition.
When I make the backwards transition, though, something strange happens: upon the transition's start, the blue square is being drawn below the green square (in terms of their elevation) and it starts moving to the top right corner as expected. While what I'd want to do is keep the blue square on top of the green square and move it to the top right corner w/o change of its elevation.
Is there something that I miss?
Relevant parts of code:
transition.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="together">
<changeBounds>
<targets>
<target android:targetId="@id/square_view"/>
</targets>
</changeBounds>
<slide android:slideEdge="top">
<targets>
<target android:targetId="@+id/green_square_view"/>
</targets>
</slide>
</transitionSet>
Scenes:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<View
android:id="@+id/green_square_view"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_marginStart="72dp"
android:layout_marginTop="216dp"
android:background="#0cfc28"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@id/square_view"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_marginBottom="180dp"
android:background="@color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>
and
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<View
android:id="@id/square_view"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="@color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.931"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.044" />
</android.support.constraint.ConstraintLayout>
MainActivity:
package aga.android.sample.transitionssample
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.transition.*
import android.util.Log
import android.view.ViewGroup
import android.widget.Button
class MainActivity : AppCompatActivity() {
private lateinit var sceneRoot: ViewGroup
private var currentSceneIndex = 0
private var scenes: Array<Scene> = emptyArray()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sceneRoot = findViewById(R.id.scene_root_view)
scenes = arrayOf(
Scene.getSceneForLayout(sceneRoot, R.layout.scene1, this),
Scene.getSceneForLayout(sceneRoot, R.layout.scene2, this)
)
val transition = TransitionInflater.from(this).inflateTransition(R.transition.move_animation)
findViewById<Button>(R.id.button).setOnClickListener {
currentSceneIndex = (currentSceneIndex + 1) % 2
TransitionManager.go(scenes[currentSceneIndex], transition)
}
}
}
Upvotes: 2
Views: 293
Reputation: 4330
The green_square_view
is not present in the second scene.xml you posted. If you add the green_square_view
to this scene too, the green square will be behind the blue square for both directions. However in this case the Slide
animation is not played any more, because the green square does not disappear. This can be fixed easily with android:visibility="invisible"
for the newly added green_square_view
, because the Slide animation reacts to Views that are not available any more as well as Views that change the Visibility.
I tried to debug what is causing this behavior. In the end I found this part in the documentation that could be applicable:
... For example, if a View was simply removed from its parent, then the View will be added into a ViewGroupOverlay and passed as the view parameter in onDisappear(ViewGroup, View, TransitionValues, TransitionValues). If a visible View is changed to be GONE or INVISIBLE, then it can be used as the view and the visibility will be changed to VISIBLE for the duration of the animation.
The mentioned ViewGroupOverlay
is drawn on top of what is in this view group. So this could explain the behavior. However I'm not 100% sure this is causing the problem. Nevertheless having the view in both scenes fixes the problematic behavior.
Upvotes: 1