Android 确定动画后ImageView共享元素的最终大小
我有许多共享元素,通过Android 确定动画后ImageView共享元素的最终大小,android,animation,android-animation,android-transitions,shared-element-transition,Android,Animation,Android Animation,Android Transitions,Shared Element Transition,我有许多共享元素,通过ActivityOptions.makeSceneTransitionAnimation在两个活动之间转换。当我进入第二个活动时,我想确定ImageView的最终目标大小,以便设置ImageView的适当宽度。我相信这样做将允许它右边的对象(也是一个共享元素)平稳过渡 ImageView是一个具有固定高度和wrap\u内容宽度的fitStart缩放类型。图像将动态加载,并从第一个活动缩小到第二个活动,因此我不知道最终宽度。在转换开始之前,我想设置ImageView的Layo
ActivityOptions.makeSceneTransitionAnimation
在两个活动之间转换。当我进入第二个活动时,我想确定ImageView
的最终目标大小,以便设置ImageView
的适当宽度。我相信这样做将允许它右边的对象(也是一个共享元素)平稳过渡
ImageView
是一个具有固定高度和wrap\u内容
宽度的fitStart
缩放类型。图像将动态加载,并从第一个活动缩小到第二个活动,因此我不知道最终宽度。在转换开始之前,我想设置ImageView
的LayoutParams
宽度,以匹配转换结束后的最终宽度
当前,此ImageView
的wrap\u content
属性会导致其右侧的元素不知道其最终静止位置,因此在返回并降落到正确位置之前,它会向右离开屏幕
这是动画的gif。第一个元素是正确设置动画的ImageView
,第二个元素是ImageView
右侧的按钮:
请注意,当第二个活动返回到第一个活动时,第二个元素平稳地过渡回屏幕左侧,因为结束位置已知
当我给ImageView
一个特定的宽度,比如100dp
,而不是wrap\u content
(然后在转换完成后将其更改回wrap\u content
),第二个元素会更平滑地移动到其最终的静止位置,但由于ImageView
将被动态加载和缩放,我事先不知道XML中图像的真实宽度,因此在转换后,当我将第二个元素更改为wrap\u content
时,它总是会突然移动
因此,我想确定ImageView
的目标宽度,并在第二个活动中开始转换之前以编程方式设置它,以便第二个元素知道它需要向左走多远。我尝试过使用ViewTreeObserver
和TransitionValues
但是我不知道如何获得ImageView转换到的最终宽度
在第二个活动的onCreate
中,我是否可以调用一些东西来确定转换后ImageView的最终宽度?
编辑 我在中尝试了该解决方案,但它报告了ImageView的开始宽度,而不是它转换到的最终宽度。以下是我正在切换的两项活动的布局,仅供参考: 请注意,我正在移动和缩小ImageView 我调整了答案的代码,因为我没有使用支持库,必须在
onPreDraw()调用中转到imageView.getViewTreeObserver()
,以避免出现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可以保证吗
如果安卓能告诉我共享元素目标的最终大小,那就太好了。情况是这样的:如果你在第二个活动中将资源从@drawable/first\u element
更改为@drawable/first\u element\u thumb
,你将不会再经历这种行为。缺点是,每次转换开始时,您都会看到一个小故障,这是因为在转换开始之前,可绘制图像正从高分辨率更改为低分辨率
以下是300毫秒动画时间:
以下是5000毫秒动画时间:
如果您希望转换不会出现该问题,那么解决方案是在转换视图时开始从高分辨率可绘制转换,并将该可绘制转换为低分辨率。你可以在他的文章中看到对这一特征的描述。您将编写自定义转换类,如。此图像来自何处?如果它是您的后端,您可以控制它,那么我建议您将图像的大小与图像url一起传递。在此信息中,您可以定义ImageView
所需的纵横比,因此它具有固定的宽度和高度。谢谢。不过我还是有个问题。编辑我的问题。如果你在github发布了一个简单的项目,我会看一看。下面是一个简单的例子:我意识到在创建这个项目时,我也会在转换结束后将大图像替换为缩略图,以便显示更好的图像版本。如果我不这样做,并将图像设置回wrap_内容,它实际上保持为较大图像的全宽,即使在过渡之后也是如此。所以也许我不应该把它设置回包装内容。但问题仍然是,我正在经历一点痛苦重新构建最终宽度(包括较小图像的右边缘)。非常感谢您查看代码并帮助解释。我甚至没有想到在过渡后将其更改为缩略图会产生如此大的影响。