使用自定义视图中的共享元素启动活动

时间:2015-12-03 16:08:45

标签: java android android-animation shared-element-transition activity-transition

我想在两个活动之间创建一个动画,并将图像作为共享元素,请参阅Customize Activity Transitions

我的问题:在源活动中,图像在自定义视图的画布上绘制: - (

有没有办法将此图像用作共享元素,还是必须添加真正的ImageView?

1 个答案:

答案 0 :(得分:0)

您不能仅共享图片,但可以共享整个自定义视图。这意味着当共享元素传输到已启动的Activity时,整个自定义View将从调用Activity中消失。如果您的自定义视图只有图像,那就没问题,但如果它描绘其他内容,那将是灾难性的。

如果您只想共享图像,则必须创建一个视图(例如ImageView)并将图像移动到该图像然后共享它。这样,当共享元素被传输时,它会从调用活动中正确隐藏。

共享元素实际上不会在活动之间移动视图,它们只是共享一个'快照'作为位图的视图和视图的位置。在已启动的活动中,具有给定转换名称的视图将在该位置布局。您可以根据需要使用快照。默认情况下,不使用快照。

所以你需要这样的代码:

public void launchActivity(final Intent intent, final CustomView view) {
    final Bitmap bitmap = view.getSharedImage();
    ImageView imageView = new ImageView(view.getContext());
    imageView.setBitmap(bitmap);
    LayoutParams layoutParams = view.createSharedImageLayoutParams();
    final ViewGroup parent = (ViewGroup)view.getParent();
    parent.addView(imageView, layoutParams);
    parent.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            parent.getViewTreeObserver().removeOnPreDrawListener(this);
            customView.hideSharedImage();
            ActivityOptions activityOptions = ActivityOptions.
                makeSceneTransitionAnimation(this, imageView, "destName");
            startActivity(intent, activityOptions.toBundle();
        }
    });
    setExitSharedElementCallback(new SharedElementCallback() {
        @Override
        public void onSharedElementsArrived(List<String> sharedElementNames,
            List<View> sharedElements, OnSharedElementsReadyListener listener) {
            super.onSharedElementsArrived(sharedElementNames, sharedElements,
                listener);
            parent.removeView(imageView);
            customView.showSharedImage();
        }
    });
}

我没有特别尝试过上述内容,但这是它的本质。如果您不想使用较新的onSharedElementsArrived,您可以创建一个侦听onVisibilityChanged的自定义ImageView。如果您有退出转换,您也可以监听它的结尾。您只需要一些触发器来告诉您重置状态,以便移除ImageView并且您的自定义视图应该再次绘制图像。

在上面的示例中,我将ImageView放在与自定义View相同的父级中。将它放入DecorView可以获得更大的灵活性,但是您必须弄清楚全局位置是什么,它还将覆盖屏幕上的所有内容。或者,因为我将ImageView添加到父级,这对所有父级都不起作用(例如ListView,LinearLayout)。您知道自己的视图层次结构,并且您必须选择最佳位置。

或者,您可以将自定义视图更改为自定义ViewGroup,并将可共享图像包含为ImageView!听起来比较容易。