繁体   English   中英

如果我的手机处于浅色或深色模式,如何制作带有文本和背景颜色的 Android 启动画面?

[英]How can I make an Android splash screen with text & background color that changes if my phone is in light or dark mode?

我已经为此工作了一段时间,不幸的是,如果不使用图像,我无法达到预期的效果。 我已经研究了 Stack Overflow 和几乎所有地方,但仍然没有找到完全可以做到这一点的解决方案。

我仍在尝试做的是:

  • 手机处于浅色模式 > 启动画面为白色背景,中间是黑色的 ABC 字样

  • 手机处于暗模式 > 启动画面为黑色背景,中间为白色的 ABC 字样

这是我到目前为止所拥有的:

SplashActivity.cs

namespace Japanese.Droid
{
    [Activity(Label = "Anki+", Theme = "@style/LaunchTheme", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {

样式文件

<style name="LaunchTheme" parent="Theme.AppCompat">
    <item name="android:windowBackground">@drawable/splash_screen</item>
    <item name="android:navigationBarColor">#ffffff</item>
</style>

飞溅屏幕.xaml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white"/>
    <item>
        <bitmap android:src="@drawable/splash_logo"
                android:tileMode="disabled"
                android:gravity="center"
                android:layout_gravity="center"/>
    </item>
</layer-list>

splash_screen_night.xaml

<?xml version="1.0" encoding="UTF-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/black"/>
    <item>
        <bitmap android:src="@drawable/splash_logo"
                android:tileMode="disabled"
                android:gravity="center"
                android:layout_gravity="center"/>
    </item>
</layer-list>

飞溅活动

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;

namespace Test.Droid
{
    [Activity(Label = "Test+", Theme = "@style/LaunchTheme", MainLauncher = true, NoHistory = true)]
    public class SplashActivity : Activity
    {

        public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
        {
            base.OnCreate(savedInstanceState, persistentState);

            //==================================== Code to hide the bottom 3 buttons on Android.
            int uiOptions = (int)Window.DecorView.SystemUiVisibility;
            uiOptions |= (int)SystemUiFlags.LowProfile;
            uiOptions |= (int)SystemUiFlags.Fullscreen;
            uiOptions |= (int)SystemUiFlags.HideNavigation;
            uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
            //===================================

            base.SetTheme(Resource.Style.MainTheme);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        }

        // Launches the startup task
        protected override void OnResume()
        {
            base.OnResume();

            //==================================== Code to hide the bottom 3 buttons on Android.
            int uiOptions = (int)Window.DecorView.SystemUiVisibility;
            uiOptions |= (int)SystemUiFlags.LowProfile;
            uiOptions |= (int)SystemUiFlags.Fullscreen;
            uiOptions |= (int)SystemUiFlags.HideNavigation;
            uiOptions |= (int)SystemUiFlags.ImmersiveSticky;
            Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
            //===================================

            System.Threading.Tasks.Task startupWork = new System.Threading.Tasks.Task(() => { SimulateStartup(); });
            startupWork.Start();
        }


        // Simulates background work that happens behind the splash screen
        async void SimulateStartup()
        {
            await System.Threading.Tasks.Task.Delay(1000); // Simulate a bit of startup work.
            StartActivity(new Intent(Application.Context, typeof(MainActivity)));
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

        public override void OnBackPressed() { }
    }
}

这使用了图像,但我想用文本来做。

有谁知道一种方法来做到这一点。 我已经尽可能多地研究了这一点,向两个 Android 开发人员寻求帮助,但仍然没有人能想出一个简单的解决方案来做到这一点而不使用图像。

是否可以仅使用文本而不是Xamarin Android 应用程序的图像来执行此操作?

要实现这一点,您需要在 Android 项目的 Layout 文件夹中创建一个 SplashScreen.xml。 您还需要在两个文件夹中创建样式,values 和 values-night。

您还需要一个单独的 SplashActivity.cs。 我在此附上代码。

  1. 启动画面.xml

     <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:background="#fff" android:id="@+id/splashview"> <TextView android:id="@+id/txtAppVersion" android:text="Anki+" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="30dp" android:layout_marginBottom="30dp" android:textColor="#000" android:textSize="24sp" android:gravity="center_vertical" android:layout_centerHorizontal="true"/> </RelativeLayout>
  2. 值文件夹中的 Styles.xml。

     <style name="MainTheme" parent="MainTheme.Base"> <item name="android:textAllCaps">false</item> </style> <style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> <item name="windowActionModeOverlay">true</item> <item name="elevation">0dp</item> </style> <style name="LaunchTheme" parent="Theme.AppCompat"> <item name="android:windowNoTitle">true</item> <item name="android:windowActionBar">false</item> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowDisablePreview">true</item> </style>

  3. values-night 文件夹中的 Styles.xml。

     <style name="MainTheme" parent="MainTheme.Base"> <item name="android:textAllCaps">false</item> </style> <style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> <item name="windowActionModeOverlay">true</item> <item name="elevation">0dp</item> </style> <style name="LaunchTheme" parent="Theme.AppCompat"> <item name="android:windowNoTitle">true</item> <item name="android:windowActionBar">false</item> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item> <item name="android:windowDisablePreview">true</item> </style>

  4. SplashActivity.cs

     using System; using Android.App; using Android.Content; using Android.Content.Res; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Plugin.CurrentActivity; namespace MyProject.Droid { [Activity(Label = "MyProject+", Theme = "@style/LaunchTheme", MainLauncher = true, NoHistory = true)] public class SplashActivity : Activity { public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState) { base.OnCreate(savedInstanceState, persistentState); //==================================== Code to hide the bottom 3 buttons on Android. int uiOptions = (int)Window.DecorView.SystemUiVisibility; uiOptions |= (int)SystemUiFlags.LowProfile; uiOptions |= (int)SystemUiFlags.Fullscreen; uiOptions |= (int)SystemUiFlags.HideNavigation; uiOptions |= (int)SystemUiFlags.ImmersiveSticky; Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions; //=================================== base.SetTheme(Resource.Style.MainTheme); Xamarin.Essentials.Platform.Init(this, savedInstanceState); } // Launches the startup task protected override void OnResume() { base.OnResume(); SetContentView(Resource.Layout.SplashScreen); bool isDarkTheme; //var isDarkTheme = Preferences.Get("isDarkTheme", false); if (Build.VERSION.SdkInt >= BuildVersionCodes.Froyo) { var uiModeFlags = CrossCurrentActivity.Current.AppContext.Resources.Configuration.UiMode & UiMode.NightMask; if (uiModeFlags == UiMode.NightYes) isDarkTheme = true; else isDarkTheme = false; } else isDarkTheme = false; if (isDarkTheme) { FindViewById<RelativeLayout>(Resource.Id.splashview).SetBackgroundColor(Android.Graphics.Color.ParseColor("#000000")); FindViewById<TextView>(Resource.Id.txtAppVersion).SetTextColor(Android.Graphics.Color.ParseColor("#FFFFFF")); } else { FindViewById<RelativeLayout>(Resource.Id.splashview).SetBackgroundColor(Android.Graphics.Color.ParseColor("#FFFFFF")); FindViewById<TextView>(Resource.Id.txtAppVersion).SetTextColor(Android.Graphics.Color.ParseColor("#000000")); } // FindViewById<TextView>(Resource.Id.txtAppVersion).Text = $"Version {PackageManager.GetPackageInfo(PackageName, 0).VersionName}"; //==================================== Code to hide the bottom 3 buttons on Android. int uiOptions = (int)Window.DecorView.SystemUiVisibility; uiOptions |= (int)SystemUiFlags.LowProfile; uiOptions |= (int)SystemUiFlags.Fullscreen; uiOptions |= (int)SystemUiFlags.HideNavigation; uiOptions |= (int)SystemUiFlags.ImmersiveSticky; Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions; //=================================== System.Threading.Tasks.Task startupWork = new System.Threading.Tasks.Task(() => { SimulateStartup(); }); startupWork.Start(); } // Simulates background work that happens behind the splash screen async void SimulateStartup() { await System.Threading.Tasks.Task.Delay(1000); // Simulate a bit of startup work. StartActivity(new Intent(Application.Context, typeof(MainActivity))); } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } public override void OnBackPressed() { } } }

您是否尝试过使用 daynight 主题? 在你的样式文件中是这样的

<style name="LaunchTheme" parent="Theme.AppCompat.DayNight">
<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:navigationBarColor">#ffffff</item>
</style>

让我知道它是否有效!

您实际上并不需要 SplashActivity。 只需在可绘制文件夹中使用 layerlist splash_screen.xml 即可。 将 MainActivity 的主题设置为 SplashTheme,并在调用 base.OnCreate 之前的 MainActivity 的 OnCreate 添加行 SetTheme(Resource.Style.RealApplicationTheme) 以便真正的 AppTheme 接管。

确保您的启动主题包含以下内容

<item name="android:windowBackground">@drawable/splash_screen</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>

这样,只要设备进行冷启动,您的启动画面就会一直停留在屏幕上。 因此,您无需担心处理额外的活动和一些人为的超时。 您可以通过在包含冷启动实际时间段的日志中搜索字符串“display”来测量显示时间。 可实现低于 1 秒的显示时间。

显然,在稍后的热启动中,您几乎看不到启动画面,因为启动时间要快得多,因为您的应用程序已经在内存中。

一旦你做对了,然后启用启动跟踪,让你的启动时间更快。

res文件夹下的两个值文件夹中为背景和前景创建颜色:

  • 夜间模式的values-night文件夹
  • 日间模式的values文件夹

对于res/values-night/colors.xml夜间模式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="splashForeground">#FFFFFF</color>
    <color name="splashBackground">#000000</color>
</resources>

对于res/values/colors.xml模式:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="splashForeground">#000000</color>
    <color name="splashBackground">#FFFFFF</color>
</resources>

在您的启动画面布局中使用颜色res/layout/splash.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView  xmlns:android="http://schemas.android.com/apk/res/android"
        android:text="ABC"
        android:textColor="@color/splashForeground"
        android:background="@color/splashBackground"

        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="24sp"
        />

您可以使用代码来确定设备主题,并基于此设置文本和颜色。

以下是 Android 文档中关于提供替代资源的一些引用。

额外信息

夜间模式

night notnight
  • 晚上:夜间
  • 晚上:白天

在 API 级别 8 中添加。

如果夜间模式处于自动模式(默认),这可能会在您的应用程序生命周期中发生变化,在这种情况下,模式会根据一天中的时间而变化。 您可以使用 UiModeManager 启用或禁用此模式。 有关这如何在运行时影响您的应用程序的信息,请参阅处理运行时更改。


(我不知道您是否已经完成了这些步骤,因为每个闪屏都有一个样式,但是由于您无法更改文本颜色,我还是会包含这些步骤)

1º -创建 2 个可绘制的 XML 文件

创建 2 个名为splash_screen.xmlsplash_screen_night.xml 的可绘制文件:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
    <item>
        <TextView
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:textColor="#00000"
          android:text="Text in Center" />
    </item>
</layer-list>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
    <item>
        <TextView
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:textColor="#FFFFFF"
          android:text="Text in Center" />
    </item>
</layer-list>

2º - 创建夜间主题

创建一个名为values-night的文件夹以实现深色主题启动画面,并将其添加到名为values的现有文件夹中以实现浅色主题启动画面。

注意:这是“魔法”发生的地方,Android 将根据设备 NightMode 使用 values 或 values-night,notnight 将与 night 相同,但对于 DayMode

在 values-night 文件夹中,创建一个空的styles.xml文件,并添加样式以包含 Dark Theme 初始屏幕:

<resources>
    <style name="LaunchTheme" parent="Theme.AppCompat">
        <item name="android:windowBackground">@drawable/splash_screen_night</item>
    </style>
</resources>

当然,在values>style.xaml ,Light Theme 启动画面

<style name="LaunchTheme" parent="MainTheme">
    <item name="android:windowBackground">@drawable/splash_screen</item>
</style>

3º 更新 MainActivity.cs 以使用新的 LauchTheme

更新 MainActivity 以确保它使用新创建的 LaunchTheme 作为启动画面。 Activity 属性使用以下值:

Theme = "@style/LaunchTheme"
LaunchMode = LaunchMode.SingleTop

例如:

[Activity(Label = "DarkModeSplashScreen", Icon = "@mipmap/icon", Theme = "@style/LaunchTheme", LaunchMode = LaunchMode.SingleTop, MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]

然后在base.OnCreate之前的OnCreate方法中:

protected override void OnCreate(Bundle savedInstanceState)
{
    //...

    base.SetTheme(Resource.Style.MainTheme);
    base.OnCreate(savedInstanceState);

    //...
}

这是为您的应用实施日/夜主题的简单且最佳的解决方案。 请按照步骤操作。

第一步:更改为 DayNight 主题

导航到您的 styles.xml 文件并将您的父主题更改为 DayNight

<style name="LaunchTheme" parent="Theme.AppCompat.DayNight">
    <!-- Theme attributes -->

</style>

这将使您的应用能够检测白天和黑夜的配置更改。 注意:就像其他主题一样,这个主题也有其变体,例如Theme.AppCompat.DayNight.NoActionBar

第二步:为您的 DayNight 主题添加属性

<style name="LaunchTheme" parent="Theme.AppCompat.DayNight.NoActionBar">

    <!-- Other attributes might be present here by default such as 'colorPrimary' -->

    <!-- These colors are going to be defined on next step -->
    <item name="android:textColor">@color/textColor</item>
    <item name="android:windowBackground">@color/windowBackgroundColor</item>
</style>

在这个例子中,我们使用 textColor 和 windowBackground 属性。 textColor 是应用程序范围的文本视图默认颜色属性,windowBackground 是活动窗口背景的默认属性。

您可以稍后根据您的需求和您对 Themes & Styles 的理解选择不同的方法。

第三步:定义颜色

导航到您的 colors.xml 并添加这些颜色。

<resources>
<color name="textColor">#000000</color>
<color name="windowBackgroundColor">#FFFFFF</color>
</resources>

第四步:创建夜间限定颜色文件

它是如何在 Android Studio 中完成的:右键单击 values 文件夹 -> New -> Values 资源文件,将您的文件命名为“colors”并向其添加 NightMode Qualifier。

如果不存在,这将在其中创建一个“values-night”文件夹和colors.xml。

如果在用于 Xamarin 开发的 IDE 中无法使用此方法,请手动创建文件:在“res”文件夹下,创建“values-night”文件夹。 然后在“values-night”文件夹下创建“colors.xml”文件。

第五步:在你的 NightMode 限定颜色文件中定义相同的颜色

导航到“values-night”文件夹下新创建的colors.xml文件并添加这些颜色。

<resources>
<color name="textColor">#FFFFFF</color>
<color name="windowBackgroundColor">#000000</color>
</resources>

请注意,颜色资源名称相同但它们具有不同的值。

第六步:使用主题

将您在第一步中定义的样式设置为您的应用程序范围主题或您的 Splash 活动主题。 (你已经这样做了)

完成后,您的应用程序现在将对昼夜配置做出反应。

测试

在 Android 版本 >= Q 的设备上运行项目并打开/关闭设备夜间模式。

或者将这些代码添加到您的应用程序类的 onCreate 函数中

AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_YES); // This code will force night mode configuration for your app. Add it to see how your app looks in night mode.

AppCompatDelegate.setDefaultNightMode(
        AppCompatDelegate.MODE_NIGHT_NO); // This code will force day mode configuration for your app. Add it to see how your app looks in day mode.

重要提示:请确保您没有覆盖预期的视觉结果,例如,将硬编码颜色值直接设置为您的 TextView。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM