Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scene transition with nested shared element

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.

enter image description here enter image description here enter image description here

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.

like image 842
nhaarman Avatar asked May 29 '16 17:05

nhaarman


People also ask

Which of the following transitions is a shared elements transition?

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.

What is shared transition?

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.

How to add animation in Fragment in android?

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).

What is shared elements in react native?

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.


1 Answers

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

  • matching resource ids or
  • matching transition names

for views participating in the transition.

like image 73
keyboardsurfer Avatar answered Oct 15 '22 23:10

keyboardsurfer