Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
340 views
in Technique[技术] by (71.8m points)

android - Shared element transition : activity into fragment nested in another activity

i am trying to add shared element transition into my app.

Scenario is that user clicks on image thumbnail which than opens another activity with full screen image view.

This works fine if shared view is hosted directly within layout of target activity. Works smoothy for enter/exit animation. But when i'am trying to achieve similar effect within fragment which is nested in target activity this approach doesn't work. Funny thing is that enter animation is not showed, but exit animation is working fine .

Another even more complicated view hierarchy is that if target view (ImageView) is hosted within view pager which is hosted in frame layout of target activity.

Does someone had same issue ?

Edit: My click listener code

public class OnClickPicture extends OnClickBase {
  private ObjectPicture object;

  public OnClickPicture(Activity_Parent activity, ObjectPicture object) {
    super(activity);
    this.object = object;
  }

  public void onClick(View v) {

    picasso.load(object.getFullUrl()).fetch();
    Intent intent = new Intent(activity, ActivityPicture.class);
    intent.putExtra("picture_object", helper.gson.toJson(object));

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && v != null) {
      Pair<View, String> p1 = Pair.create(v, "image");
      ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, p1);
      activity.startActivity(intent, options.toBundle());
    } else {
      activity.startActivity(intent);
    }

  }

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The way that transitions work require the new Activity to be created, measured and laid out before any animations can happen. That's so that it can find the view that you want to animate and create the appropriate animation.

In your case this isn't happening because, as stated in the docs, all FragmentTransaction.commit() does is schedule work to be done. It doesn't happen immediately. Therefore when the framework creates your Activity it cant find the view that you want to animate. That's why you don't see an entry animation but you do see an exit animation. The View is there when you leave the activity.

The solution is simple enough. First of all you can try FragmentManager.executePendingTransactions(). That still might not be enough. The transitions framework has another solution:

In the onCreate of Activity postponeEnterTransition(). This tells the framework to wait until you tell it that its safe to create the animation. That does mean that you need to tell it that its safe (via calling startPostponedEnterTransition()) at some point. In your case that would probably be in the Fragments onCreateView.

Here's an example of how that might look like:

Activity B

@Override
protected void onCreate(Bundle savedInstanceState) {
    // etc
    postponeEnterTransition();
}

Fragment B

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View sharedView = root.findViewById(R.id.shared_view);
    sharedview.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            sharedview.getViewTreeObserver().removeOnPreDrawListener(this);
            getActivity().startPostponedEnterTransition();
            return true;
        }
    });
}

Thanks to Alex Lockwood for his detailed blog posts about the Transitions framework.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...