android - 具有半径的 CardView 上的共享元素转换

标签 android android-animation android-cardview android-transitions shared-element-transition

我已经研究这个问题好几个星期了,但我仍然无法解决这个问题。

所以,我有一个 CardView,其中包含一个带有 ImageView 的 LinearLayout。

without radius

如果没有这个半径,共享元素过渡会无缝运行。但是,当我向该 CardView 添加半径 (app:cardCornerRadius="25dp") 时,共享元素转换看起来很难看,因为它先删除半径然后开始动画

with radius transition

第一种方法:ObjectAnimator

我创建了 ObjectAnimator 来为卡片上的半径值设置动画,并在动画结束后开始过渡。

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)。

第二种方法 - ChangeImageTransform

我读过 StackOverflow post使用像 ChangeImageTransform 和 ChangeBounds 这样的转换类。

我确实按照建议定义了我的应用程序主题(my_transition 包含 ChangeImageTransform transitionSet)

<item name="android:windowSharedElementEnterTransition">@transition/my_transition</item>
<item name="android:windowSharedElementExitTransition">@transition/my_transition</item>

但是没用..

第三种方法 - 朴素

我最后一次尝试是强制目标 ImageView 的半径也为 25dp。因为可能我的 CardView 被转换成正方形是因为目标 ImageView 是正方形的,但正如您所猜测的那样,它不起作用。

第四种方法 - 不使用 CardView

如您所见,我正在使用 Penguin 图像并使用 CardView 制作半径。我可以使用图像变换使图像变圆,但我仍然认为这不是创建共享元素过渡的正确方法。

这是我的问题,有没有一种方法可以在不先删除半径的情况下使用 CardView 半径进行共享元素转换?

最佳答案

终于解决了。对于那些有兴趣的人,方法如下:

为什么它在开始过渡之前删除半径?因为目标 ImageView 没有任何半径。

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 时,它并不明显,但它实际上变成了目标共享 View 。

  1. 要实现从半径到无半径的过渡,您必须将目标共享 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>
  1. 一定要将 makeSceneTransition 更改为使用“card”而不是“animalImage”

ListActivity.class

ActivityOptionsCompat option = ActivityOptionsCompat
.makeSceneTransitionAnimation(ListActivity.this, cardView, "card");

startActivity(intent, option.toBundle());
  1. 在 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();
            }
        });
}
  1. 享受平稳过渡

final animation

注意:要点 layoutactivities

关于android - 具有半径的 CardView 上的共享元素转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42274607/

相关文章:

android - 在三星安卓浏览器上启用真正的固定定位

android - Android 中的 SQLiteDiskIOException

android - 清除整个适配器并添加新元素时的 RecyclerView 动画

android - 沿路径动画 ImageView Android

android - 如何在cardview上添加彩色边框?

java - 如何在适配器 onBind() 中比较 2 个具有不同元素集的列表?

android - 在 ICS 的 webViewClient 中播放 SWF 文件?

android - 使 View 逐渐出现

android - 如何让 Recycler 在网格中查看前四个项目,然后在线性项目中查看

android - 在 Android 应用程序中配置 SSL 客户端证书以在 Tomcat 上的 Web 服务器中进行客户端身份验证