Android 了解退出/重新进入共享元素转换
我正在对Android L中的共享元素转换进行一些初步探索。我设置的一个简单示例在活动转换期间有一个从屏幕顶部到屏幕底部的图像视图,我延长了转换持续时间,这样我就可以看到事情在运行。到目前为止,为了理解共享元素转换是如何工作的,我遇到了两个问题 1) 仅使用输入/返回转换时(退出/重新输入设置为null)。“输入”转换很好,但当按下“后退”按钮时,“视图”将动画显示一段时间,并停止,然后重新出现在最终位置。看起来与类似,但我已将所有存在/重新进入转换设置为null,因此不确定为什么会发生这种情况 2) 仅使用退出/重新进入转换时(输入/返回设置为null)。什么都没有发生,视图在屏幕上向下转换,就像它跟随默认的回车转换一样(300毫秒的持续时间),当按下“后退”时,视图将弹出回其原始位置 如何使用退出/重新进入转换 这是我的密码: activity_main.xmlAndroid 了解退出/重新进入共享元素转换,android,android-5.0-lollipop,shared-element-transition,activity-transition,Android,Android 5.0 Lollipop,Shared Element Transition,Activity Transition,我正在对Android L中的共享元素转换进行一些初步探索。我设置的一个简单示例在活动转换期间有一个从屏幕顶部到屏幕底部的图像视图,我延长了转换持续时间,这样我就可以看到事情在运行。到目前为止,为了理解共享元素转换是如何工作的,我遇到了两个问题 1) 仅使用输入/返回转换时(退出/重新输入设置为null)。“输入”转换很好,但当按下“后退”按钮时,“视图”将动画显示一段时间,并停止,然后重新出现在最终位置。看起来与类似,但我已将所有存在/重新进入转换设置为null,因此不确定为什么会发生这种情况
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:src="@drawable/ic_launcher"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Animate!"
android:id="@+id/button"
android:layout_centerVertical="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
SecondActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
getWindow().setSharedElementExitTransition(exitTransition());
getWindow().setSharedElementReenterTransition(reenterTransition());
//getWindow().setSharedElementExitTransition(null);
//getWindow().setSharedElementReenterTransition(null);
setContentView(R.layout.activity_main);
final View iView = findViewById(R.id.imageView);
iView.setTransitionName("image");
final Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
ActivityOptions options = ActivityOptions
.makeSceneTransitionAnimation(MainActivity.this, iView, "image");
startActivity(intent, options.toBundle());
}
});
}
private Transition exitTransition() {
ChangeBounds bounds = new ChangeBounds();
bounds.setInterpolator(new BounceInterpolator());
bounds.setDuration(2000);
return bounds;
}
private Transition reenterTransition() {
ChangeBounds bounds = new ChangeBounds();
bounds.setInterpolator(new OvershootInterpolator());
bounds.setDuration(2000);
return bounds;
}
}
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
//getWindow().setSharedElementEnterTransition(enterTransition());
//getWindow().setSharedElementReturnTransition(returnTransition());
getWindow().setSharedElementEnterTransition(null);
getWindow().setSharedElementReturnTransition(null);
setContentView(R.layout.activity_second);
final View iView = findViewById(R.id.imageView2);
iView.setTransitionName("image");
}
@Override
public void onBackPressed() {
super.onBackPressed();
finishAfterTransition();
}
private Transition enterTransition() {
ChangeBounds bounds = new ChangeBounds();
bounds.setDuration(2000);
return bounds;
}
private Transition returnTransition() {
ChangeBounds bounds = new ChangeBounds();
bounds.setInterpolator(new DecelerateInterpolator());
bounds.setDuration(2000);
return bounds;
}
}
onBackPressed()
中调用finishAfterTransition()
。活动
超级类已经为您完成了这项工作super.onCreate()之前调用requestFeature()
。如果您使用的是主题.材料
主题(或类似主题),则不需要请求窗口.功能\u活动\u转换
setAllowInterTransitionOverlap(false)
和setAllowReturnTransitionOverlap(false)
在这里是多余的。这些决定了活动的窗口内容转换重叠。。。它们根本不会影响活动的共享元素内容转换我记得,L中有一个bug,它会导致共享元素返回转换被中断,如果它花费的时间超过重新进入转换的持续时间。如果您调整了重新输入转换的持续时间(在调用活动上),那么应该可以解决中断问题,直到错误在MR1中得到修复
退出和重新进入转换用于在允许共享元素转换之前执行内容。例如,如果您想在传输共享元素之前提升它,那么这将在共享元素退出转换中完成。重新输入将用于执行相反的操作——在视图被传输回后将其删除。大多数应用程序都不需要它,但很少有应用程序需要它。那么,我想使用退出/重新进入转换的场景有什么例子?编辑:我也按照你的建议做了,但看起来动画还是在打嗝。我还没有找到使用退出/重新进入转换的好理由。。。事实上,它们甚至不可用于
Fragment
转换。也许其他人可以给出一个很好的答案……嗨@AlexLockwood,你能看看我几周前发布的一个问题吗?这个问题是关于在启用了转换的情况下将活动放在活动堆栈的最前面的?提前谢谢,我有几个后续问题。(1) MR1是指5.0.1版还是以后的版本?(2) 退出/重新进入共享元素转换可用于活动转换,但不可用于片段转换,这有什么原因吗?(1)MR1尚未发布。我不确定它会有什么版本。(2) 对!!片段转换是通过某种移除(隐藏/分离/移除/替换)和某种添加(显示/附加/添加/替换)来执行的。当您执行一个FragmentTransaction时,您不能很好地操作该片段来触发共享元素退出转换并同时将其删除。仅供参考,我刚刚添加了一篇博客文章来描述这些。酷,谢谢你的帖子!顺便说一句,我也在写我自己的博客文章,从以下开始:)@Geogemount我正在使用ActivityOptions Compat仍然面临相同的问题有什么建议吗
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setAllowReturnTransitionOverlap(false);
//getWindow().setSharedElementEnterTransition(enterTransition());
//getWindow().setSharedElementReturnTransition(returnTransition());
getWindow().setSharedElementEnterTransition(null);
getWindow().setSharedElementReturnTransition(null);
setContentView(R.layout.activity_second);
final View iView = findViewById(R.id.imageView2);
iView.setTransitionName("image");
}
@Override
public void onBackPressed() {
super.onBackPressed();
finishAfterTransition();
}
private Transition enterTransition() {
ChangeBounds bounds = new ChangeBounds();
bounds.setDuration(2000);
return bounds;
}
private Transition returnTransition() {
ChangeBounds bounds = new ChangeBounds();
bounds.setInterpolator(new DecelerateInterpolator());
bounds.setDuration(2000);
return bounds;
}
}