我想在两个活动之间创建一个动画,并将图像作为共享元素,请参阅Customize Activity Transitions
我的问题:在源活动中,图像在自定义视图的画布上绘制: - (
有没有办法将此图像用作共享元素,还是必须添加真正的ImageView?
答案 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!听起来比较容易。