CardView上具有半径的共享元素过渡 [英] Shared Element Transition on CardView with radius
问题描述
我已经解决这个问题了好几个星期了,但仍然无法解决这个问题.
I've been working on this problem for weeks and I'm still unable to solve this problem.
因此,我有一个CardView,其中包含带有ImageView的LinearLayout.
So, I have a CardView that contains a LinearLayout with an ImageView.
在没有半径的情况下,共享元素过渡可以无缝进行.但是,当我向该CardView添加半径(app:cardCornerRadius ="25dp")时,共享元素过渡看起来很丑,因为先删除半径然后再开始动画.
Without that radius Shared Element Transition works seamlessly. However, when I add radius (app:cardCornerRadius="25dp") to that CardView, the Shared Element Transition looks ugly because it remove the radius first and then start the animation.
第一种方法:ObjectAnimator
我创建了ObjectAnimator来对卡上的半径值进行动画处理,动画结束后,它开始过渡.
I create ObjectAnimator to animate the radius value on card, and after the animation end it start the transition.
ObjectAnimator animator = ObjectAnimator
.ofFloat(view, "radius", AppUtil.dpAsPixel(this, 25), 0);
animator.setDuration(150);
animator.addListener( // start new Activity with Transition );
animator.start();
这可以工作,但是看起来并不好,因为过渡会在开始过渡之前先等待动画完成.我需要的是半径过渡到新的Activity时正在设置动画(类似于TransitionSet中的ORDERING_TOGETHER).
This works but it doesn't looks great, because the transition wait the animation to finish before starting the transition. What I need is the radius is animating while doing transition to new Activity (something like ORDERING_TOGETHER in TransitionSet).
第二种方法-ChangeImageTransform
我已阅读 StackOverflow帖子以使用诸如ChangeImageTransform和ChangeBounds之类的转换类.
I've read a StackOverflow post to use Transformation Class like ChangeImageTransform and ChangeBounds.
我确实按照建议的方式定义了我的应用程序主题(my_transition包含ChangeImageTransform transitionSet)
I did define my application theme like it was suggested (my_transition contains ChangeImageTransform transitionSet)
<item name="android:windowSharedElementEnterTransition">@transition/my_transition</item>
<item name="android:windowSharedElementExitTransition">@transition/my_transition</item>
但这是行不通的.
第三种方法-天真
我最后的尝试是也将目标ImageView的半径也设置为25dp.因为也许我的CardView变成了正方形,因为目标ImageView是正方形,但是您可以猜到它不起作用.
My last attempt is to force the target ImageView to have a radius of 25dp too. Because maybe my CardView is transformed into square because the target ImageView is square, but as you can guess, it doesn't work.
第四种方法-不使用CardView
如您所见,我正在使用企鹅图像并使用CardView绘制半径.我可以使用图像变换"使图像变圆,但是我仍然认为这不是创建共享元素过渡的正确方法.
As you can see, I'm using Penguin images and use CardView to make a radius. I can make the image rounded by using Image Transformation, but I still don't think that's the right way to create a Shared Element Transition..
这是我的问题,有没有办法在不先删除半径的情况下使用CardView半径进行共享元素转换?
And here is my question, is there a way to make a Shared Element Transition with CardView radius works without removing the radius first?
推荐答案
我终于能够解决它.对于那些感兴趣的人,方法如下:
I finally able to solve it. For those who are interested, here's how:
为什么要在开始过渡之前移除半径?因为目标ImageView没有任何半径.
Why it remove radius before starting transition? Because the target ImageView doesn't have any radius.
activity_detail.xml
<ImageView
android:id="@+id/iv_image_cover"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:src="@{animal.imageRes}"
android:transitionName="animalImage"
tools:src="@drawable/acat"
/>
当我使用无半径的CardView时,它并不明显,但实际上已变成目标共享视图.
When I use CardView without radius, it's not noticable, but it's actually turned into target Shared View.
- 要实现从半径到无半径的过渡,必须将目标共享视图设置为四舍五入.我只是使用Card View(带有半径)包装它.
activity_detail.xml
<android.support.v7.widget.CardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:transitionName="card"
app:cardCornerRadius="25dp"
>
<ImageView
android:id="@+id/iv_image_cover"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:src="@{animal.imageRes}"
android:transitionName="animalImage"
tools:src="@drawable/acat"
/>
</android.support.v7.widget.CardView>
- 请确保将makeSceneTransition更改为使用卡"而不是"animalImage"
ListActivity.class
ActivityOptionsCompat option = ActivityOptionsCompat
.makeSceneTransitionAnimation(ListActivity.this, cardView, "card");
startActivity(intent, option.toBundle());
- 在DetailActivity中,您可以在过渡开始时启动半径动画.
DetailActivity.java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().getSharedElementEnterTransition()
.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionStart(Transition transition) {
ObjectAnimator animator = ObjectAnimator
.ofFloat(activityDetailBinding.card, "radius", 0);
animator.setDuration(250);
animator.start();
}
});
}
- 享受平稳的过渡