确定动画后ImageView共享元素的最终大小

问题描述:

我有大量的共享元素,我通过ActivityOptions.makeSceneTransitionAnimation在两个活动之间转换。当我进入第二项活动时,我想确定ImageView的最终目标尺寸是什么,以便我可以设置ImageView的适当宽度。我相信这样做会让对象(也是共享元素)的权利顺利过渡。确定动画后ImageView共享元素的最终大小

ImageView是一个fitStart scaleType具有固定的高度和wrap_content宽度。图像将被动态加载并从第一个活动缩减到第二个,所以我不知道最终的宽度。在转换开始之前,我想将宽度设置为ImageViewLayoutParams以匹配转换结束后的最终宽度。

目前,ImageViewwrap_content属性导致其右侧的元素无法知道其最终放置位置,因此它在屏幕右侧返回并着陆之前在右侧地点。

这是动画的gif。第一个元素是ImageView,正确的动画,和第二个元素是按钮,ImageView的权利:

enter image description here

注意,当第二个活动可以追溯到第一个活动,第二个元素平滑地过渡回到屏幕的左侧,因为结束位置是已知的。

当我请ImageView特定宽度等100dp代替wrap_content(然后在过渡结束后更改回wrap_content),第二元件移动更顺畅到其最后的安息的地方,但由于ImageView将是动态加载并缩放后,我不会事先知道XML中图像的真实宽度,因此在转换后将其更改为wrap_content时,总是会出现第二个元素的抖动。

enter image description here

所以我想确定ImageView的目标宽度和设置程序的过渡在第二活动开始,这样第二个元素知道如何靠左它需要去之前。我试过玩ViewTreeObserverTransitionValues,但我错过了如何获得ImageView过渡到的最终宽度。

有什么我可以调用onCreate的第二个活动来确定什么宽度的ImageView最终将在过渡后?


编辑

我试着在this answer解决方案,但它报告回的ImageView开始的宽度,而不是它的转换到最终宽度。作为参考,这些是我要切换的两个活动的布局: enter image description here

请注意,我正在移动并缩小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能否告诉我共享元素定位的最终大小,那真是太好了。

+0

这张图片的原型来自哪里?如果它是您的后端,并且您可以控制它,那么我建议您将图像的大小与图像url一起传递。在这个信息中,您可以定义您的ImageView需要的宽高比,因此它将具有固定的宽度和高度。 – rom4ek

以下是这种情况:如果您将第二次活动中的资源从@drawable/first_element更改为@drawable/first_element_thumb,您将不会遇到该行为。不足之处在于,每次启动转换时都会出现一个小故障,这是因为在转换开始之前,drawable会从高分辨率转换为低分辨率。

下面是用300ms的动画时间:

enter image description here

这里与5000毫秒的动画时间:

enter image description here

如果你想转变是没有是毛刺,不是解决的办法是从高分辨率drawable开始转换,并在转换视图时将drawable替换为低分辨率。你可以在他的"Animatable" talk中看到Nick Butcher的功能。您最终会编写您的自定义转换课程,如this one

+0

谢谢。我仍然有一个问题。编辑我的问题。 – annie

+0

如果你在github上发布了一个简单的项目,我会看看。 – azizbekian

+0

这里有一个简单的例子:https://github.com/annie-l/TransitionSample 当我创建这个项目时我意识到,为了显示更好的版本,我还在转换结束后为缩略图图像替换了大图像图片。如果我不这样做,并将图像设置回wrap_content,它实际上保持为较大的图像的全宽,即使在转换后。所以也许我不应该把它设置回wrap_content。但问题仍然是,我正在经历一些痛苦,重新构建最终宽度将会是什么(包括较小图像的右边缘)。 – annie