Почему значение для android:background все еще используется после переключения на новую тему

У меня есть это в моем Style.xml в моем приложении Xamarin.Android:

<resources>
    <!-- Splash styles -->
    <style name = "Theme.Splash" parent = "Theme.AppCompat.Light.NoActionBar">
        <item name = "android:background">@drawable/splash_drawable</item>
        <item name = "android:windowNoTitle">true</item>
        <item name = "android:windowIsTranslucent">false</item>
        <item name = "android:windowIsFloating">false</item>
        <item name = "android:backgroundDimEnabled">true</item>
    </style>
    <!-- Theme -->
    <style name = "AppTheme" parent = "Theme.AppCompat.Light.DarkActionBar">
        <!-- window:background is not set here, but even if it set (to say, @null for eg), there is no change. The value from Theme.Splash is preserved. -->
        ....


Мой MainActivity.cs выглядит так:

[Activity(
    Label = "My app",
    Icon = "@drawable/icon",
    Theme = "@style/Theme.Splash",
    MainLauncher = true,
    LaunchMode = LaunchMode.SingleTask,
    ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.Locale | ConfigChanges.LayoutDirection,
    ScreenOrientation = ScreenOrientation.Portrait
    )
]

public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        // Changing to App theme since we are in OnCreate and we are ready to
        // "hide" the splash.
        // But the android:background property value from Theme.Splash remains.
        base.Window.RequestFeature(WindowFeatures.ActionBar);
        base.SetTheme(Resource.Style.AppTheme);
        ...


Как я могу удалить то, что было установлено для android:background? Это вызывает серьезные проблемы, поскольку перекрывает все мои представления, когда приложение завершает загрузку.

ПРИМЕЧАНИЕ. Вместо этого я не могу использовать android:windowBackground в Theme.Splash, так как это приводит к смещению моей пользовательской страницы-заставки ниже строки состояния.

Я сделал странное, черт возьми, наблюдение, для которого я не могу найти никакой документации. Если я изменю имя стиля с AppTheme на Theme.AppTheme и изменю вызов в OnCreate с base.SetTheme(Resource.Style.AppTheme); на base.SetTheme(Resource.Style.Theme_AppTheme);, я получу измененное поведение... например, некоторые свойства стиля распознаются, но не все.

Ash 12.02.2019 08:10

Почему у вас вообще есть Theme = "@style/Theme.Splash", в заголовке вашей активности? Это должно быть только в вашей теме Splash, не так ли!?

FreakyAli 12.02.2019 08:46

@ G.hakim Вы имеете в виду, что это должно быть атрибутом моей активности всплеска? Если так, то да, согласен. Однако именно так это настроено в настоящее время; Я мог бы попробовать рефакторинг.

Ash 12.02.2019 09:19

Это должно быть только в атрибуте активности вашего Splash, а не в вашей MainActivity, MainActivity должна иметь только глобальную тему вашего приложения.

FreakyAli 12.02.2019 10:16

@ G.hakim Я провел рефакторинг, чтобы использовать выделенную SplashActivity, из которой я запускаю MainActivity, и теперь все работает так, как я ожидаю. если вы хотите превратить свой комментарий в ответ, я могу принять его.

Ash 13.02.2019 13:57
1
5
254
2

Ответы 2

Просто переопределите android:background внутри AppTheme.

Взгляните на комментарий, который я добавил к стилю AppTheme. Это не имеет значения, так что это не работает.

Ash 12.02.2019 07:15

См. также комментарий, который я добавил к моему вопросу.

Ash 12.02.2019 08:18

Вы упомянули, что «не можете вместо этого использовать android:windowBackground в Theme.Splash, так как это приводит к смещению моей пользовательской страницы-заставки ниже строки состояния». Попробуйте добавить:

<item name = "android:windowFullscreen">true</item>
<item name = "android:windowContentOverlay">@null</item>
<item name = "android:windowBackground">@drawable/splash_drawable</item>

это должно решить это. Убедитесь, что ваш drawable отзывчив, чтобы у вас не было проблем с разными размерами экрана и конфигурациями.

********************* Обновлять *********************

Попробуйте установить тему-заставку в файле manifest.xml в теге приложения и использовать действие-заставку, которое затем запускает MainActivity с темой приложения. Вы можете выполнить инициализацию приложения во всплывающей активности (помните, что синхронная инициализация приложения должна быть ограничена теми вещами, которые должны быть выполнены до того, как пользователь сможет получить доступ к пользовательскому интерфейсу, все остальное должно выполняться асинхронно и инициировать изменение пользовательского интерфейса через событие) . Мы почти исключительно используем этот подход, поскольку у нас обычно есть процесс аутентификации, который мы делаем здесь, и добавляем сообщения и индикаторы выполнения поверх заставки, например «Инициализация» или «Попытка аутентификации», чтобы удерживать пользователя.

Вот пример того, что я имею в виду:

В манифесте.xm. включают:

<application android:label = "@string/app_name" android:allowBackup = "true" android:theme = "@style/AppDark.Fullscreen.Splash" android:icon = "@mipmap/ic_app_launcher">
…..
<application>

В стили .xml входят:

<style name = "AppTheme" parent = "AppDark">
<style name = "AppTheme.NoActionBar">
  <item name = "windowActionBar">false</item>
  <item name = "windowNoTitle">true</item>
  <item name = "windowActionModeOverlay">true</item>
  <item name = "android:windowTranslucentStatus">true</item>
  <item name = "android:windowDrawsSystemBarBackgrounds">true</item>
  <item name = "android:statusBarColor">@android:color/transparent</item>
</style>
<style name = "AppDark" parent = "Theme.AppCompat.Light.DarkActionBar">
  <item name = "android:windowNoTitle">true</item>
  <item name = "android:windowActionBar">false</item>
  <item name = "android:colorPrimary">@color/app_background</item>
  <item name = "android:backgroundDimEnabled">true</item>
</style>
<style name = "AppLight" parent = "Theme.AppCompat.Light.NoActionBar">
  <item name = "android:windowNoTitle">true</item>
  <item name = "android:windowActionBar">false</item>
  <item name = "android:colorPrimary">@color/app_background</item>
</style>
<style name = "AppLight.Fullscreen">
  <item name = "android:windowFullscreen">true</item>
  <item name = "android:windowContentOverlay">@null</item>
</style>
<style name = "AppLight.Fullscreen.Splash">
  <item name = "android:windowBackground">@drawable/responsive_splashscreen</item>
</style>

Затем по видам деятельности:

[Activity(
Label = "@string/app_name", 
MainLauncher = true, 
Exported = true, 
LaunchMode = LaunchMode.SingleTask,
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.Locale | ConfigChanges.LayoutDirection,
ScreenOrientation = global::Android.Content.PM.ScreenOrientation.Portrait)]

public class SplashActivity : BaseActivity
{
…….

[Activity(
Label = "@string/app_name", 
Theme = "@style/AppTheme.NoActionBar"
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.Locale | ConfigChanges.LayoutDirection,
ScreenOrientation = global::Android.Content.PM.ScreenOrientation.Portrait,
WindowSoftInputMode = SoftInput.AdjustResize)]

public class MainActivity : BaseActivity
{
…….

Пробовал это, у меня не сработало. Я думаю, что это, скорее всего, связано со странным поведением, вызванным запуском MainActivity с темой Splash, а затем изменением темы.

Ash 13.02.2019 13:56

Помните, что если вы измените тему действия программно, оно не вступит в силу до тех пор, пока действие не запустит OnResume, поэтому вам нужно выйти и вернуться к действию (или закрыть/запустить, приостановить/возобновить и т. д.), чтобы изменение вступило в силу эффект, однако изменения свойства Window вступят в силу в текущем состоянии жизненного цикла.

English Dave 14.02.2019 19:08

Смотрите мое обновление для подхода, который может работать для вас.

English Dave 15.02.2019 20:10

Другие вопросы по теме