14

I have the following problem:

I'm trying to transition from Fragment A to Fragment B. There is a shared element between these fragments in the form of a Button and some other View's (see layout).

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:flipper="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.mypackage.view.IndicatorViewFlipper
        android:transitionGroup="true"
        android:id="@+id/intro_viewflipper"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        flipper:indicatorColor="@color/white"
        flipper:indicatorMargin="4dp"
        flipper:indicatorRadius="4dp"
        flipper:indicatorBarMargin="104dp"/>

    <Button
        android:id="@+id/account_create_btn"
        style="?android:attr/borderlessButtonStyle"
        android:textColor="@color/white"
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_standard_height"
        android:layout_above="@+id/txt_already_account"
        android:background="@drawable/button_yellow_selector"
        android:transitionName="create_account"
        android:text="@string/account_create_btn"
        android:textSize="24sp"
        android:textAllCaps="false" />

    <TextView
        android:id="@+id/txt_already_account"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_above="@+id/account_login_btn"
        android:layout_marginTop="24dp"
        android:text="@string/account_welcome_already_account"/>

    <Button
        android:id="@+id/account_login_btn"
        style="?android:attr/borderlessButtonStyle"
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_standard_height"
        android:layout_marginTop="8dp"
        android:layout_alignParentBottom="true"
        android:transitionName="login"
        android:background="@drawable/button_blue_selector"
        android:textColor="@color/white"
        android:textSize="24sp"
        android:textAllCaps="false"
        android:text="@string/account_create_login_btn"/>

</RelativeLayout>

What I'm trying to do is to let all the content in Fragment except for the shared element, transition (slide to the left) and let all the content form Fragment B except for the shared element slide in from the right. During this content transition I want the shared element to remain in its original position until the content transitions are done, and then let it slide to its new position in Fragment B.

This last behaviour is where it goes wrong: once I start the exit transition in Fragment A the shared element disappears and slides in from the right with the content transition of Fragment B. The behaviour of the shared element is correct if I don't add any exit/enter transitions.

The code (in Fragment A):

Fragment fragment = MyFragment.newInstance();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(this);
fragmentTransaction.add(R.id.frame_container, fragment, fragment.getClass().getSimpleName());
fragmentTransaction.addSharedElement(sharedElement, sharedElementTag);
Transition sharedElementTransaction = TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move);
sharedElementTransaction.setStartDelay(400);
fragment.setSharedElementEnterTransition(sharedElementTransaction);
setExitTransition(new Slide(Gravity.LEFT).setDuration(200));
fragment.setEnterTransition(new Slide(Gravity.RIGHT).setDuration(200));

Can anyone help me get the desired behaviour?

Update:

I've made a work around that almost does what I want using animate() on my views to slide/fade them and on completion of this animation trigger the shared element transaction:

Transition sharedElementTransition = TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.move);
sharedElementTransition.setStartDelay(400);
fragment.setSharedElementEnterTransition(sharedElementTransition);
setSharedElementReturnTransition(sharedElementTransition);

mLoginBtn.animate()
   .x(-mLoginBtn.getWidth())
   .setDuration(400)
   .start();

viewFlipper.animate()
   .x(-viewFlipper.getWidth())
   .setDuration(400)
   .setListener(new AnimatorListenerAdapter() {
   @Override
   public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        transaction.commit();
   }
})
.start();

fragment.setEnterSharedElementCallback(new SharedElementCallback() {
   @Override
   public void onSharedElementStart(List<String> sharedElementNames, List<View> sharedElements, List<View> sharedElementSnapshots) {
   super.onSharedElementStart(sharedElementNames, sharedElements, sharedElementSnapshots);
   viewFlipper.animate()
           .x(0)
           .setDuration(400)
           .setListener(null)
           .start();

   mLoginBtn.animate()
           .x(0)
           .setDuration(400)
           .start();
   });

The problem with this solution is that I can't slide in the Views of the called Fragment so there I now just fade in the Views.

Joris
  • 1,437
  • 1
  • 15
  • 22
  • Stupid question,but have you looked into [scenes](https://developer.android.com/training/transitions/scenes.html) .You could give same element Ids and then the transitions could be provided(or removed) to required elements. – Droidekas Feb 27 '15 at 11:35
  • @Droidekas I've had a look at Scenes but I'm not sure how to use them to solve my problem... I've made a work around that does almost what I want, I'll update my question with the current solution. But still looking for a way to do it with the Transitions framework. – Joris Mar 02 '15 at 15:35
  • It might help the discussion if you could elaborate as to why you need the two different button instances in the two fragments, if indeed the two buttons will share a single visual 'view' to the user. If the user just sees a single button ... then why not have a single Button instance (maintained by the Activity, or perhaps another single-purpose fragment) and then let your two content fragments acquire references to it somehow? – Mike Repass Mar 02 '15 at 16:04
  • I use two Fragments because I want each Fragment to be responsible for the behaviour of the Button, which is different in the two Fragments, and to easily make layouts for the two screens, which apart from the shared Button are completely different. If I would place the Button in the layout of the Activity I would have a hard time getting the layouts right. But if this is the only way to get the desired behaviour of the shared element then I might give it a shot. – Joris Mar 02 '15 at 16:21
  • Could you provide a video of the problem? It would help understanding better what you are trying to achieve and what the problem is – Quanturium Mar 04 '15 at 20:12
  • @Quanturium I'll try to do that as soon as I find some time, maybe this weekend. – Joris Mar 05 '15 at 16:34

1 Answers1

0

If all you need is to animate the fragments while the button stays still, you can move the button to the activity and animate the fragment.