共享元素转换(Shared Element Transition)是Android 5.0 (API 21)引入的动画功能,允许两个Activity之间共享的视图元素平滑过渡,提供更流畅的用户体验。
在Android Nougat (API 25)上共享元素转换可能不起作用的常见原因:
transitionName
不匹配<!-- styles.xml -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementsUseOverlay">false</item>
</style>
// 在第一个Activity中
View sharedElement = findViewById(R.id.shared_element);
sharedElement.setTransitionName("unique_transition_name");
// 在第二个Activity的onCreate中
View sharedElement = findViewById(R.id.shared_element);
sharedElement.setTransitionName("unique_transition_name");
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
activity,
sharedElement, // 共享的视图
"unique_transition_name" // 必须与setTransitionName一致
);
startActivity(intent, options.toBundle());
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N ||
Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
// Nougat特定修复
getWindow().setSharedElementsUseOverlay(false);
}
确保共享元素不是SurfaceView或TextureView的子类,这些视图在API 25上可能有转换问题。
// 第一个Activity
public void startSecondActivity(View view) {
ImageView imageView = findViewById(R.id.shared_image);
imageView.setTransitionName("shared_image");
Intent intent = new Intent(this, SecondActivity.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
this,
imageView,
"shared_image"
);
startActivity(intent, options.toBundle());
}
// 第二个Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N ||
Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
getWindow().setSharedElementsUseOverlay(false);
}
ImageView imageView = findViewById(R.id.shared_image);
imageView.setTransitionName("shared_image");
// 延迟执行转换
postponeEnterTransition();
imageView.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
imageView.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
共享元素转换常用于:
如果问题仍然存在,可以考虑:
通过以上方法,应该能够解决Android Nougat (API 25)上共享元素转换不起作用的问题。