Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Shared Elements

I have the following situation inside of a soccer application.
We want to implement the shared elements between all these activities.

Shared Elements Situation

In my viewholder on the first Activity for the match I have set a android:transitionName which corresponds to the same transitionName on the second Activity.

<!-- item_viewholder (first activity) -->
<CustomViewContainingImageViewAndTextView
     android:id="@+id/item_match_hometeam"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:transitionName="@string/transition_morph_match_header_homeTeam" />

<!-- header (second activity) -->
<CustomViewContainingImageViewAndTextView
     android:id="@+id/item_match_hometeam_header"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:transitionName="@string/transition_morph_match_header_homeTeam" />

I start the second Activity with

final String awayTeamTransition = activityContext.getString(R.string.transition_morph_match_header_awayTeam);
final String homeTeamTransition = activityContext.getString(R.string.transition_morph_match_header_homeTeam);
final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
                   activityContext,
                   Pair.create(homeTeam, homeTeamTransition),
                   Pair.create(awayTeam, awayTeamTransition));
activityContext.startActivity(intent, options.toBundle());

Now this transition works fine but what if I want to have an even deeper detail.
Displaying statistics about the selected team and I want to have shared transition there too?

I tried setting the transitionName programmatically when the CustomViewContainingImageViewAndTextView was clicked to the new transitionName.

final String teamViewTransition = activityContext.getString(R.string.transition_morph_teamview_to_detail);
//teamView is the view that was clicked.
ViewCompat.setTransitionName(teamView, teamViewTransition);

final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
     activityContext,
     Pair.create(teamView, teamViewTransition));
activityContext.startActivity(teamInfoActivityIntent, options.toBundle());

this transitionName corresponds to the ImageView on the third Activity

<ImageView
   android:id="@+id/team_info_header_logo"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:transitionName="@string/transition_morph_teamview_to_detail" />

However the enterTransition fails, but the exitTransition works!
However this breaks the exitTransition from 2 --> 1

Sight. Hope someone takes some time to figure this out.

Thanks in advance

like image 504
timr Avatar asked May 27 '16 19:05

timr


People also ask

What is a shared element?

What are shared elements? A shared element transition determines how views that are present in two fragments transition between them. For example, an image that is displayed on an ImageView on both Fragment A and Fragment B transitions from A to B when B becomes visible.

What is transition animation in Android?

Android's transition framework allows you to animate all kinds of motion in your UI by simply providing the starting layout and the ending layout.


1 Answers

Beyond any doubt, the problem is because you are changing transitionName of the view that you want to share from second Activity to third. But you should simply keep that transitionName in the second Activity but change transitionName of the view in third Activity's onCreate method, according to what we want to share from second Activity.

So let's keep our transition from first Activity to second, as it's working as expected. Let's look at the second Activity: we just need to send the transitionName of view, that we want to share as an extra of Intent to third Activity and then assign this value programmatically to the shared view in third Activity.

So here is the code of our second Activity:

View homeTeam = findViewById(R.id.home_team_detail);
View awayTeam = findViewById(R.id.away_team_detail);

View.OnClickListener onTeamClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Activity activityContext = MultipleElementsDetail.this;
        final ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
                activityContext,
                Pair.create(v, v.getTransitionName()));
        startActivity(new Intent(activityContext, SingleElementDetail.class)
           .putExtra("shared_element_transition_name", v.getTransitionName()), options.toBundle());
    }
};

homeTeam.setOnClickListener(onTeamClickListener);
awayTeam.setOnClickListener(onTeamClickListener);

So what I did here is just created the same OnClickListener for both teams, which creates shared transition, and starts new activity with Intent having transitionName of shared view as an extra.

And then in third Activity I've just get this extra from Intent and set it as a transitionName of shared view:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_single_element_detail);

    View team = findViewById(R.id.team_single);

    String transitionName = getIntent().getStringExtra("shared_element_transition_name");
    if (!TextUtils.isEmpty(transitionName)) {
        ViewCompat.setTransitionName(team, transitionName);
    }
}

And as a result we have something like this (I've used explode transition to better see the difference between activities):

enter image description here

Hope that helps and exactly the same what you want! :)

like image 188
romtsn Avatar answered Oct 11 '22 20:10

romtsn