如何为应用程序设置主题,以避免错误的颜色过渡?

and*_*per 15 android android-theme

背景

我正在我的"app manager"应用程序中开发主题选择器功能,并且我已成功为每个活动动态设置主题.

再次:这不是关于为活动设定主题.这实际上适合我.

问题

这些活动正在显示正确的主题,但应用程序本身在启动应用程序时,无论我做什么,都会显示错误的主题.

这是一个问题,因为当用户打开应用程序时,他将看到应用程序主题的背景,并且仅在片刻之后,活动将显示用户选择的主题.

因此,如果应用程序具有白色背景,并且用户选择了具有黑色背景的主题,则顺序将为:

应用程序显示白色背景 - >活动正在启动并显示黑色背景.

在截图中:

在此输入图像描述

所以这是错的.在这种情况下,我需要它来显示黑色到黑色的背景.

仅当用户选择了基于Holo-light的主题(默认情况下应用程序具有此主题)时,它才能正常工作,因为颜色与打开应用程序时右侧显示的活动上的颜色相匹配.

我试过的

我有一个想法,设置应用程序的主题是空的一切,希望没有显示过渡,使用类似的东西:

<application
    ...
    android:theme="@android:style/Theme.Translucent.NoTitleBar" >
Run Code Online (Sandbox Code Playgroud)

事实上,这里的一些人提出了类似的解决方案.

这有效,但它会导致糟糕的体验,因为在某些设备上显示第一个活动需要一些时间,因此,用户有很长时间没有看到任何内容,就像应用程序不是正在推出.

这个问题

我该如何解决这个问题?

我已经尝试在从Application扩展的类中设置主题,但它不会做任何事情,无论我在这个类中调用它.

Ric*_*ier 9

透明的应用程序主题与淡入动画

我最初的建议是使用透明全屏应用程序主题(没有操作栏).

结合这一点,我总是建议从应用程序主题到活动主题的淡入淡出的alpha动画.这可以防止在操作栏出现时对用户造成震动.

OP的代码将保持几乎相同,除了更改清单主题,并在onCreate()一些基本活动类的方法中添加alpha动画,如下例所示:


清单主题定义为:

android:theme="@android:style/Theme.Translucent.NoTitleBar"
Run Code Online (Sandbox Code Playgroud)

基本活动onCreate()方法:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    // set your custom theme here before setting layout
    super.setTheme(android.R.style.Theme_Holo_Light_DarkActionBar);

    setContentView(R.layout.activity_main);

    overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
Run Code Online (Sandbox Code Playgroud)

基本淡入:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromAlpha="0.0"
    android:toAlpha="1.0" />
Run Code Online (Sandbox Code Playgroud)

基本淡出(不是真的需要,但为了完整性):

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromAlpha="1.0"
    android:toAlpha="0.0" />
Run Code Online (Sandbox Code Playgroud)

当然,这里的动画持续时间比你投入生产的时间长 - 它们很长,所以你可以在开发阶段看到它们.


更新#1:

随后在@EmanuelMoecklin的评论中注意到,@ androiddeveloper认为这是考虑到的.它也包含在dentex的回答中.但是,正如OP所述,特别是在旧设备上的弱点是用户在尝试启动应用程序时没有获得反馈.该应用程序似乎需要很长时间才能启动.

在KitKat上,情况并非如此,因为状态栏和软键从透明变为黑色,而屏幕的其余部分仍然是透明的.

另一种方法是使用全屏黑色背景作为应用程序主题.这就是Bitspin for Timely所做的,显然是基于该应用程序中令人惊叹的用户界面而被Google收购.因此,在许多情况下,这种方法似乎是可以接受的.


更新#2:

为了加快对发布的看法,普通黑色主题的替代方案是使用带有应用程序徽标的全屏图像 - "闪屏"风格.一旦启动,再次淡出活动.

透明主题使用透明的全屏图像是不可能的.Android忽略图像的透明度(或将透明图像叠加到黑色背景上).OP在评论中指出了这一点.

我们既可以有没有图像的透明主题,也可以有带图像的不透明主题(也许是另一个问题的有趣主题).


关于使用Manifest别名的说明

@ sergio91pt的另一个建议是在清单中为不同的活动使用别名.

虽然在某些情况下这可能是一种有用的技术,但在这种情况下它有一些缺点:

  1. 当主启动器别名发生更改时,即每次用户更改主题时,用户为活动创建的任何HOME屏幕快捷方式将停止工作.
  2. 某些设备/启动器激活和停用不同的别名非常慢.根据我的经验,这可能需要几秒钟(Galaxy Nexus 4.1 iirc),在此期间您要么没有可见的启动图标,要么您有2个图标.
  3. 每个可能的主题都需要一个不同的别名 - 如果有许多不同的主题,这可能会很麻烦.

  • @RichardLeMesurier也是我的想法,但遗憾的是我不是一个设计师.我也认为没有人喜欢闪屏.所以我在考虑最小的工作,这只是动态设置背景,所以我问了这个问题,这表明这可能是一个不可能完成的任务.:( (3认同)

Hai*_*ang 9

有点晚了,但这可能就是答案.我偶然发现了它.

没有入场活动,没有自定义动画,没有黑客攻击.只是主题中的一个属性.Android深入挖掘其资源.

将以下属性添加到您的应用主题:

<!--
  ~ From Theme.NoDisplay, this disables the empty preview window probably
  ~ with an incorrect theme.
  -->
<item name="android:windowDisablePreview">true</item>
Run Code Online (Sandbox Code Playgroud)

你完成了.好好享受!