确定动画后ImageView共享元素的最终大小
我有大量的共享元素,我通过ActivityOptions.makeSceneTransitionAnimation
在两个活动之间转换。当我进入第二项活动时,我想确定ImageView
的最终目标尺寸是什么,以便我可以设置ImageView
的适当宽度。我相信这样做会让对象(也是共享元素)的权利顺利过渡。确定动画后ImageView共享元素的最终大小
该ImageView
是一个fitStart
scaleType具有固定的高度和wrap_content
宽度。图像将被动态加载并从第一个活动缩减到第二个,所以我不知道最终的宽度。在转换开始之前,我想将宽度设置为ImageView
的LayoutParams
以匹配转换结束后的最终宽度。
目前,ImageView
的wrap_content
属性导致其右侧的元素无法知道其最终放置位置,因此它在屏幕右侧返回并着陆之前在右侧地点。
这是动画的gif。第一个元素是ImageView
,正确的动画,和第二个元素是按钮,ImageView
的权利:
注意,当第二个活动可以追溯到第一个活动,第二个元素平滑地过渡回到屏幕的左侧,因为结束位置是已知的。
当我请ImageView
特定宽度等100dp
代替wrap_content
(然后在过渡结束后更改回wrap_content
),第二元件移动更顺畅到其最后的安息的地方,但由于ImageView
将是动态加载并缩放后,我不会事先知道XML中图像的真实宽度,因此在转换后将其更改为wrap_content
时,总是会出现第二个元素的抖动。
所以我想确定ImageView
的目标宽度和设置程序的过渡在第二活动开始,这样第二个元素知道如何靠左它需要去之前。我试过玩ViewTreeObserver
和TransitionValues
,但我错过了如何获得ImageView过渡到的最终宽度。
有什么我可以调用onCreate
的第二个活动来确定什么宽度的ImageView最终将在过渡后?
编辑
我试着在this answer解决方案,但它报告回的ImageView开始的宽度,而不是它的转换到最终宽度。作为参考,这些是我要切换的两个活动的布局:
请注意,我正在移动并缩小ImageView。
我调整了,因为我没有使用支持库,不得不搬到imageView.getViewTreeObserver()
在onPreDraw()
呼吁避免了答案的代码IllegalStateException
:
postponeEnterTransition();
final ImageView imageView = (ImageView) findViewById(R.id.image_view);
final ViewGroup.LayoutParams imageViewLayoutParams = imageView.getLayoutParams();
final ViewTreeObserver viewTreeObserver = imageView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw() {
imageView.getViewTreeObserver().removeOnPreDrawListener(this);
// You can acquire the width here
logoLayoutParams.width = imageView.getWidth();
Log.i(TAG, "width is " + imageViewLayoutParams.width);
imageView.setLayoutParams(imageViewLayoutParams);
// `imageView` has been laid out, but not yet been drawn
startPostponedEnterTransition();
return true;
}
});
的日志报告的998的宽度,这是活动1中的imageView的较大尺寸(其在转换之前的开始尺寸)。所以第二元素仍然飞离屏幕。
现在我已经有了这个代码,我可以使用较大图像的宽高比信息来计算出较小图像的最终宽度,因为我知道最终高度,但这是保证与fitStart
scaleType?
如果知道Android能否告诉我共享元素定位的最终大小,那真是太好了。
以下是这种情况:如果您将第二次活动中的资源从@drawable/first_element
更改为@drawable/first_element_thumb
,您将不会遇到该行为。不足之处在于,每次启动转换时都会出现一个小故障,这是因为在转换开始之前,drawable会从高分辨率转换为低分辨率。
下面是用300ms的动画时间:
这里与5000毫秒的动画时间:
如果你想转变是没有是毛刺,不是解决的办法是从高分辨率drawable开始转换,并在转换视图时将drawable替换为低分辨率。你可以在他的"Animatable" talk中看到Nick Butcher的功能。您最终会编写您的自定义转换课程,如this one。
谢谢。我仍然有一个问题。编辑我的问题。 – annie
如果你在github上发布了一个简单的项目,我会看看。 – azizbekian
这里有一个简单的例子:https://github.com/annie-l/TransitionSample 当我创建这个项目时我意识到,为了显示更好的版本,我还在转换结束后为缩略图图像替换了大图像图片。如果我不这样做,并将图像设置回wrap_content,它实际上保持为较大的图像的全宽,即使在转换后。所以也许我不应该把它设置回wrap_content。但问题仍然是,我正在经历一些痛苦,重新构建最终宽度将会是什么(包括较小图像的右边缘)。 – annie
这张图片的原型来自哪里?如果它是您的后端,并且您可以控制它,那么我建议您将图像的大小与图像url一起传递。在这个信息中,您可以定义您的ImageView需要的宽高比,因此它将具有固定的宽度和高度。 – rom4ek