我的应用程序在显示主活动之前会显示一个启动画面,持续1秒钟。启动画面和主活动共享一个图像,需要从启动画面的中心动画到主活动布局的顶部。
如果将启动画面实现为主活动中的<layer-list>
背景图像(参见正确的启动画面或如何制作启动画面?),那么如何实现这种动画就不是很明显了。因此,我决定将启动画面实现为普通活动,并使用共享元素转换来在两个活动之间动画显示该图像。最初,我在启动活动中使用了以下onCreate()
实现:
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
ImageView imageView = (ImageView)findViewById(R.id.imageView);
String transitionName = ViewCompat.getTransitionName(imageView);
Intent intent = new Intent(this, LoginActivity.class);
ActivityOptionsCompat options =
ActivityOptionsCompat.makeSceneTransitionAnimation(
this, imageView, transitionName);
imageView.postDelayed(() -> {
ActivityCompat.startActivity(SplashActivity.this, intent, options.toBundle());
finish();
}, 1000);
}
}
这种方式存在两个问题:
- 在调用
startActivity()
后立即调用finish()
会导致闪屏活动窗口在动画开始之前隐藏/销毁,这会导致主屏幕在动画期间短暂闪现。 - 从主活动返回时,自动触发共享元素返回转换,在主活动窗口关闭后的500毫秒内,图像似乎悬浮在主屏幕上。返回转换失败,因为闪屏活动已经调用了finish(),因此不再在返回栈中。
finish()
调用包装在postDelay() Runnable中,以确保它只在共享元素转换完成后才被调用。 1500ms延迟适用于我的应用程序,但该值应根据其他用例所需的时间进行调整。...
imageView.postDelayed(() -> {
ActivityCompat.startActivity(SplashActivity.this, intent, options.toBundle());
imageView.postDelayed(this::finish, 1500);
}, 1000);
为了解决第二个问题,我重写了主活动的
onBackPressed()
方法,直接调用 finish()
,从而避免了默认实现中对 finishAfterTransitions()
的调用。这可以防止活动尝试执行共享元素返回转换。@Override
public void onBackPressed() {
finish();
}
任何改进此解决方案的替代方法或建议将不胜感激。