共享元素转换:将活动转换为嵌套在另一个活动中的片段

Mat*_*lak 25 android android-fragments android-transitions

我正在尝试将共享元素转换添加到我的应用程序中.

场景是用户点击图像缩略图,而不是使用全屏图像视图打开另一个活动.

如果共享视图直接托管在目标活动的布局中,则此方法正常.适用于进入/退出动画.但是当我试图在嵌套在目标活动中的片段中实现类似的效果时,这种方法不起作用.有趣的是,输入动画没有显示,但退出动画工作正常.

另一个更复杂的视图层次结构是,如果目标视图(ImageView)托管在视图寻呼机中,该视图寻呼机托管在目标活动的帧布局中.

有人有同样的问题吗?

编辑:我的点击监听器代码

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);
    }

  }

}
Run Code Online (Sandbox Code Playgroud)

Mid*_*fko 33

转换工作的方式需要在任何动画发生之前创建,测量和布置新的Activity.这样它就可以找到你想要动画的视图并创建适当的动画.

在你的情况下,这不会发生,因为正如文档中所述,所有FragmentTransaction.commit()都会安排工作.它不会立即发生.因此,当框架创建您的Activity时,它无法找到您想要设置动画的视图.这就是为什么你没有看到一个条目动画,但你确实看到了一个退出动画.当您离开活动时,视图就在那里.

解决方案很简单.首先,您可以尝试FragmentManager.executePendingTransactions().这仍然可能还不够.转换框架有另一种解决方案:

在onCreate of Activity postponeEnterTransition()中.这告诉框架要等到你告诉它创建动画是安全的.这确实意味着您需要在某个时刻告诉它安全(通过调用startPostponedEnterTransition()).在您的情况下,可能会在片段onCreateView中.

这是一个如何看起来像这样的例子:

活动B.

@Override
protected void onCreate(Bundle savedInstanceState) {
    // etc
    postponeEnterTransition();
}
Run Code Online (Sandbox Code Playgroud)

片段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;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

感谢Alex Lockwood 关于Transitions框架的详细博客文章.

  • 完美而干净的解释。谢谢 (2认同)