主题切换时的过渡(或Activity.recreate())

Transition when theme switching (or Activity.recreate())

我的目标是 API 级别 14+,所以我在我的应用程序中使用 Activity.recreate() 进行主题切换。效果很好,只是黑屏会闪烁约 0.5 秒。

我曾经认为这里不可能提供更好的体验,直到我看到一个 material 设计的应用程序成功地通过交叉淡入淡出切换了主题。但不幸的是我没能记起它的名字,因为我前段时间从我的 phone 中卸载了它。

我试过 Activity.overridePendingTransition(),它没有用,我相信原因是 recreate() 调用很像配置更改,所以机制不同于完成和启动一个全新 activity.


(在尝试找到该应用程序时,我遇到了另一个神奇的主题切换应用程序,即使没有调用 recreate()。嗯......有人知道这个技巧是怎么做到的吗?)

Theme switching on the fly GIF

Who said themes were immutable? Changing the primary and accent colors on…


编辑:

我发现上面的 GIF 有点分散了原始问题的注意力,所以我把它变成了 link。

我原来的问题是,有什么方法可以通过适当的过渡来改变(切换)主题吗?

通过暴力更改屏幕上的所有内容并不是切换应用程序的主题;虽然看起来是这样,但它会导致很多问题。

很遗憾地发现上面的 GIF 可能只是一个骇人听闻的暴力攻击,但仍然感谢@Emanuel Moecklin 指出这一点。

但我还是希望能有一个“(真正的)通过过渡切换主题”的解决方案,或者有人告诉我 Activity.recreate() 不能动画,没有其他方法可以更好地切换主题。

查看类似问题的答案:

您在问题中提到的应用程序的作用不是更改主题,而是更改状态栏、操作栏和导航栏的颜色:

状态栏:

getWindow().setStatusBarColor(colorStatus);

操作栏:

ActionBar actionBar = getSupportActionBar();
actionBar.setBackgroundDrawable( new ColorDrawable( colorAction ) );

导航栏:

getWindow().setNavigationBarColor(colorStatus);

我的猜测是通过设置两个可见元素(浮动操作按钮和选项卡导航)的背景色来改变强调色。标签导航颜色可以这样改变:

ActionBar actionBar = getSupportActionBar();
actionBar.setStackedBackgroundDrawable( new ColorDrawable( accentColor ) );   

经过这么多年,我学会了一个简单的方法。

而不是Activity.recreate(),使用下面的代码片段:

finish();
startActivity(new Intent(this, getClass()));
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);

它会给你一个很好的主题之间的动画。

奖励:您可以手动保存和恢复实例状态以保留 UI 状态,并通过覆盖 Activity 上的输入相关方法 (dispatch*Event()) 在重新启动期间忽略用户输入。