I'm trying to use the Transitions API to animate a shared element between two ViewGroups. The goal is that the green view travels 'out of its parent's bounds' towards the new position.
I have the following layouts:
first.xml
:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#f00" />
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#00f">
<View
android:id="@+id/myview"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#0f0" />
</FrameLayout>
</RelativeLayout>
second.xml
:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#f00">
<View
android:id="@+id/myview"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:background="#0f0" />
</FrameLayout>
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#00f" />
</RelativeLayout>
However, I can't get this to work properly. The default transition just fades everything out and in, the ChangeBounds
transition does nothing at all, and the ChangeTransform
does not look right either.
The code I'm using:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
setContentView(R.layout.first);
View myView1 = findViewById(R.id.myview);
myView1.setTransitionName("MYVIEW");
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
View second = LayoutInflater.from(MainActivity.this).inflate(R.layout.second, root, false);
View myView2 = second.findViewById(R.id.myview);
myView2.setTransitionName("MYVIEW");
Scene scene = new Scene(root, second);
Transition transition = new ChangeTransform();
transition.addTarget("MYVIEW");
transition.setDuration(3000);
TransitionManager.go(scene, transition);
}
}, 2000);
}
Now I am manually able to do this by creating the animation myself using a ViewOverlay
. However, I'm looking for a solution using the Transitions API. Is this even possible?
Also, I am not looking to 'flatten' the hierarchy. I am intentionally nesting the View to account for more complex use cases.
Android also supports these shared elements transitions: changeBounds - Animates the changes in layout bounds of target views. changeClipBounds - Animates the changes in clip bounds of target views. changeTransform - Animates the changes in scale and rotation of target views.
Shared Element Transition is one of the most seen animations in Android apps. This type of animation is used when we have to open an item from a ListView or RecyclerView. Shared Element Transition in Android determines how shared element views are animated from activity to activity or fragment to fragment.
To animate the transition between fragments, or to animate the process of showing or hiding a fragment you use the Fragment Manager to create a Fragment Transaction . Within each Fragment Transaction you can specify in and out animations that will be used for show and hide respectively (or both when replace is used).
react-native-shared-element is a "primitive" that runs shared element transitions entirely native without requiring any passes over the JavaScript bridge. It works by taking in a start- and end node, which are obtained using the <SharedElement> component.
Yes, reparenting is possible with the Android transition API. There is one major restriction to consider when reparenting views:
Usually, every child view is only allowed to draw within it's parents bounds. This will result in the view disappearing when it hits the border of its initial parent and reappear in the new parent after a short while.
Turn off child clipping all the way up your view hierarchies of the relevant scenes by setting android:clipChildren="false"
on all relevant parents.
In more complex hierarchies, such as adapter backed views, it's more performant to toggle child clipping dynamically via a TransitionListener
.
You'll also have to use ChangeTransform
in order to reparent the view, either instead of ChangeBounds
or add it to a TransitionSet
.
There is no need for transition name or target at this level of transitions since the framework will figure that out itself. If things get more complicated you'll want to have either
for views participating in the transition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With