Android应用程序启动时如何以编程方式更改窗口背景?

9

我很清楚如何使用清单中的主题和windowBackground标签在Android中设置活动的启动画面。

最近一位客户要求“根据每天某些事件更改启动画面”。 我几乎可以肯定这是不可能的,但我还是决定尝试用以下代码:

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;
        }
    }
}

很明显这不起作用。

是否有人已经尝试过实现这个或者有更好的想法?

谢谢。

编辑:

创建一个虚假的活动或片段来显示启动画面将是容易的,但会在应用程序启动时留下不愉快的白色(或黑色,取决于主题)闪烁。

这个问题是关于通过编程方式改变启动画面的可行性,使其与在清单中硬编码得到相同的结果。


你能做到这个吗? - thiagolr
2
很抱歉,似乎是不可能的。 您可以在您的应用程序启动时设置启动屏幕,但它不可更改,正如此处所述:https://www.bignerdranch.com/blog/splash-screens-the-right-way/ 或者,如果您能够容忍打开应用程序时空白屏幕半秒钟的时间,那么您可以创建一个类似的视图,您可以随时更改它。 - Marco Fedele
3个回答

0
如果您删除启动画面,并通过创建一个全屏幕活动来模拟它,在其中显示所需的图像n秒钟,会有什么效果?

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);
    }
}

或者Kotlin:

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)
}

然而,这并没有解决应用程序启动时出现的白屏 / 黑屏问题。

我们的解决办法是在AndroidManifest.xml中将一个中性主题(仅背景色,与所有变体中的主题背景相同)设置为android:theme,然后在onApplyThemeResource中切换到正确的变体,在我们的情况下,它只是一些徽标覆盖着彩色背景。

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

这虽不是完美的,但对我们来说已经足够好了 - 也许会对其他人有所帮助。


-2

如果你只想改变背景,那么操作栏的颜色和外观也可以用类似的方式来完成。

    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);
        }
    }

这应该适用于当前的活动。


正如我在_EDIT_中所述,我期望的不是那种类型的启动画面。 - Marco Fedele

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接