Android 共享元素转换错误
Android shared element transition bug
如您在此 video 中所见,我正在尝试为新 activity 的打开设置动画。打开 activity 时图像动画正确,但返回时就惨遭失败(我正在使用 supportFinishAfterTransition()
)
我已经尝试了在这里或 Google 上找到的各种方法,但没有任何效果,即:
在 res/transition 下定义过渡:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<changeImageTransform/>
</transitionSet>
然后在主 activity 和我打开的样式中使用它:
<!-- enable window content transitions -->
<item name="android:windowActivityTransitions">true</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform</item>
我也在我的 java 代码中尝试了同样的方法:
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().setSharedElementExitTransition(...);
getWindow().setSharedElementEnterTransition(...);
从我的观点来看,我正在开始新的 activity 这样做:
private void openNewActivity() {
String transitionName = "details";
Intent intent = new Intent(mContext, ActivityCardDetails.class);
ViewCompat.setTransitionName(mImageView, transitionName);
//noinspection unchecked
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation((MainActivity)mContext,
mImageView, // The view which starts the transition
transitionName // The transitionName of the view we’re transitioning to
);
ActivityCompat.startActivity((MainActivity) mContext, intent, options.toBundle());
}
这是启动动画的 ImageView:
<ImageView
android:layout_width="match_parent"
android:layout_height="180dp"
android:id="@+id/business_card_image"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
这是应该为其设置动画的第二个 ImageView:
<ImageView
android:id="@+id/business_card_image"
android:layout_width="match_parent"
android:layout_height="180dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="@bool/isFitSystemWindows"
android:transitionName="@string/transition_card_details"
app:layout_collapseMode="parallax" />
PS:我正在使用 Glide 加载图像,因为这是用户创建的内容,我无法控制图像的纵横比。
Glide.with(mContext)
.load(toLoad)
.fitCenter()
.centerCrop()
.crossFade()
.into(mImageView);
几周来我一直在为这个问题苦苦挣扎,但我似乎无法克服它。
为什么它不能动画化它的边界?
谢谢!
更新:显然这个错误与图像宽度有关。如果我将宽度设置为一个常量(比如 200dp),动画在两种方式下都运行良好,但如果我将图像宽度设置为 match_parent
,则 return 动画被破坏。
更新 2:我几乎可以说这个错误与图像加载库有关(Glide 或 Picasso 都有这个问题)
显然这个问题已经在 here and 之前描述过了。问题确实来自图像加载器。
诀窍是将 .dontTransform()
与
一起使用
ActivityCompat.postponeEnterTransition(this)
ActivityCompat.startPostponedEnterTransition(ActivityCardDetails.this)
仅在正确加载图像时播放动画。
如您在此 video 中所见,我正在尝试为新 activity 的打开设置动画。打开 activity 时图像动画正确,但返回时就惨遭失败(我正在使用 supportFinishAfterTransition()
)
我已经尝试了在这里或 Google 上找到的各种方法,但没有任何效果,即:
在 res/transition 下定义过渡:
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeBounds/>
<changeImageTransform/>
</transitionSet>
然后在主 activity 和我打开的样式中使用它:
<!-- enable window content transitions -->
<item name="android:windowActivityTransitions">true</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_transform</item>
<item name="android:windowSharedElementExitTransition">
@transition/change_image_transform</item>
我也在我的 java 代码中尝试了同样的方法:
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().setSharedElementExitTransition(...);
getWindow().setSharedElementEnterTransition(...);
从我的观点来看,我正在开始新的 activity 这样做:
private void openNewActivity() {
String transitionName = "details";
Intent intent = new Intent(mContext, ActivityCardDetails.class);
ViewCompat.setTransitionName(mImageView, transitionName);
//noinspection unchecked
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation((MainActivity)mContext,
mImageView, // The view which starts the transition
transitionName // The transitionName of the view we’re transitioning to
);
ActivityCompat.startActivity((MainActivity) mContext, intent, options.toBundle());
}
这是启动动画的 ImageView:
<ImageView
android:layout_width="match_parent"
android:layout_height="180dp"
android:id="@+id/business_card_image"
android:adjustViewBounds="true"
android:scaleType="centerCrop" />
这是应该为其设置动画的第二个 ImageView:
<ImageView
android:id="@+id/business_card_image"
android:layout_width="match_parent"
android:layout_height="180dp"
android:scaleType="centerCrop"
android:fitsSystemWindows="@bool/isFitSystemWindows"
android:transitionName="@string/transition_card_details"
app:layout_collapseMode="parallax" />
PS:我正在使用 Glide 加载图像,因为这是用户创建的内容,我无法控制图像的纵横比。
Glide.with(mContext)
.load(toLoad)
.fitCenter()
.centerCrop()
.crossFade()
.into(mImageView);
几周来我一直在为这个问题苦苦挣扎,但我似乎无法克服它。
为什么它不能动画化它的边界?
谢谢!
更新:显然这个错误与图像宽度有关。如果我将宽度设置为一个常量(比如 200dp),动画在两种方式下都运行良好,但如果我将图像宽度设置为 match_parent
,则 return 动画被破坏。
更新 2:我几乎可以说这个错误与图像加载库有关(Glide 或 Picasso 都有这个问题)
显然这个问题已经在 here and
诀窍是将 .dontTransform()
与
ActivityCompat.postponeEnterTransition(this)
ActivityCompat.startPostponedEnterTransition(ActivityCardDetails.this)
仅在正确加载图像时播放动画。