Android在应用程序启动时以编程方式更改windowBackground

时间:2016-06-16 14:31:10

标签: android splash

我很清楚如何使用manifest中的主题和标记 windowBackground 在Android中设置活动的 splash

一位客户最近出现了要求“根据白天的某些事件改变启动画面”。 我几乎可以肯定它无法完成,但我决定用这段代码试一试:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        int random = (int) Math.abs(System.currentTimeMillis() % 3);

        switch (random) {

            case 0:
                setTheme(R.style.FullscreenTheme1);
                break;

            case 1:
                setTheme(R.style.FullscreenTheme2);
                break;

            default:
                setTheme(R.style.FullscreenTheme3);
                break;
        }
    }
}

显然这不起作用。

有人已经试图帮助这个或者有更好的主意吗?

谢谢

编辑:

创建一个虚假的活动或片段以显示为初始屏幕将很容易,但在应用程序启动时会留下令人不快的白色(或黑色取决于主题)闪烁。

这个问题是关于以编程方式更改启动画面的可行性,其结果与在清单中对其进行硬编码相同。

3 个答案:

答案 0 :(得分:0)

如果您删除Splash并通过在全屏幕中创建一个显示所需图像n秒的活动来模拟它,该怎么办?

答案 1 :(得分:0)

一个更好/更早的主题选择位置是在onApplyThemeResource中(在onCreate之前调用):

public class MyApplication extends Application {

    @Override
    protected void onApplyThemeResource(Resources.Theme theme, int resid,
        boolean first) {
        int random = (int) Math.abs(System.currentTimeMillis() % 3);

        int myRes;
        switch (random) {
            case 0:
                myRes = R.style.FullscreenTheme1;
                break;

            case 1:
                myRes = R.style.FullscreenTheme2;
                break;

            default:
                myRes = R.style.FullscreenTheme3;
                break;
        }
        super.onApplyThemeResource(theme, myRes, first);
    }
}

或科特林:

override fun onApplyThemeResource(theme: Resources.Theme, resid: Int, first: Boolean) {
    val myRes = when(System.currentTimeMillis() % 3) {
        0L -> R.style.FullscreenTheme1
        1L -> R.style.FullscreenTheme2
        else -> R.style.FullscreenTheme3
    }
    super.onApplyThemeResource(theme, myRes, first)
}

但是,这不能解决应用程序启动时出现白色/黑色闪烁的问题。

我们的解决方法是在android:theme中将{strong>中性主题(仅背景色,与所有变体中的主题背景相同)设置为AndroidManifest.xml ,然后切换到onApplyThemeResource中的右侧变体,在我们的示例中,该变体只是彩色背景上的一些徽标。

结果:应用程序“闪烁”纯色背景(而不是黑白,直到Android初始化了该应用程序),然后在此背景上显示徽标(取决于onApplyThemeResource中确定的状态)在我们初始化应用程序时。

这并不完美,但对我们来说已经足够了-也许它可以帮助其他人。

答案 2 :(得分:-1)

如果你只想改变背景,可以尝试这个,动作栏的颜色和外观也可以用同样的方式完成。

    package com.example;

    import java.util.ArrayList;

    public class WelcomeFragment extends Fragment {
        private LinearLayout mainLayout;

        //since you seem only interested in the background color changing, using a theme might seem to be overkill
        //that is if its for a very short time
        //but then a theme is better if you are concerned about branding
        //what i have here is basically to cahnge the background color
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_welcome, container, false);
mainLayout = (LinearLayout) v.findViewById(R.id.main_layout);
            colorList.add(R.color.accent);
            colorList.add(R.color.primary_light);
            colorList.add(R.color.secondary_light);
            colorList.add(R.color.secondary);
            colorList.add(R.color.secondary_dark);
            colorList.add(R.color.colorPrimaryDark);
            colorList.add(R.color.primary_dark);
            colorList.add(R.color.primary);

            return v;
        }

        ArrayList<Integer> colorList = new ArrayList<>();

        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
           new CountDownTimer((1000 * 14), 1000) {//set my timer to 14 seconds, restarts if a certain condition is not met
           //set the timing to appropriate values or if you are just interested in a particular event do this in that section
                public void onTick(long millisUntilFinished) {
                    //do update here
                    mainLayout.setBackgroundColor(getResources().
                            getColor(colorList.get((int) (millisUntilFinished / 1000) % 7)));
                }

                public void onFinish() {
                    if (!done)
                        this.start();
                }
            }.start();

            super.onViewCreated(view, savedInstanceState);
        }
    }

这适用于当前的活动。