Xamarin.Forms应用切换至Main Activity时启动页缩放问题求助
嘿,我遇到过类似的Android版本差异导致的启动页动画问题,帮你梳理下可能的原因和解决办法:
先明确下你的问题场景
你开发的是Xamarin.Forms跨平台应用,核心是内嵌浏览器保障Cookie安全,现在在Android 10的Pixel 2设备上,从启动页SplashActivity切换到MainActivity时,启动页会出现缩放效果,但Android 9模拟器完全正常。
先贴下你的关键代码方便大家参考:
启动页Activity代码
[Activity(Theme ="@style/Theme.Splash", MainLauncher = true, NoHistory = true)] public class SplashActivity : Activity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); /*... 省略部分代码 ...*/ StartActivity(typeof(MainActivity)); } }
主Activity代码
[Activity(Icon = "@drawable/icon", Theme = "@style/MainTheme.Base", MainLauncher = false)] public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); } /* ... 其他代码 ...*/ }
Styles.xml配置
<?xml version="1.0" encoding="utf-8" ?> <resources> <style name="Theme.Splash" parent="@android:style/Theme.NoTitleBar.Fullscreen"> <item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowFullscreen">true</item> <item name="android:windowActionBar">true</item> </style> <style name="MainTheme.Base" parent="@android:style/Theme.NoTitleBar.Fullscreen"> <item name="windowNoTitle">true</item> <item name="windowActionBar">false</item> <item name="colorPrimary">#2196F3</item> <item name="colorPrimaryDark">#1976D2</item> <item name="colorAccent">#FF4081</item> <item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item> </style> <style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog"> <item name="colorAccent">#FF4081</item> </style> </resources>
补充的splash_screen.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <color android:color="#fff"/> </item> <item> <bitmap android:src="@drawable/alwbg" android:tileMode="disabled" android:gravity="center"/> </item> </layer-list>
为什么会出现这个问题?
这个缩放异常是Android 10(API 29)的专属问题,主要和以下两点有关:
- 主题属性不匹配:启动页主题
Theme.Splash设置了android:windowActionBar="true",但主Activity的MainTheme.Base用的是不带android:前缀的windowActionBar="false",这种属性定义方式和值的双重差异,在Android 10的窗口动画逻辑里会触发不必要的缩放过渡,而Android 9对这种差异的兼容性更好。 - Android 10的动画逻辑更新:Android 10优化了窗口切换的动画效果,当两个Activity的全屏、ActionBar等核心主题属性不一致时,系统会默认添加缩放动画来过渡,旧版本系统没有这个行为。
解决办法,按优先级尝试
1. 统一主题的ActionBar属性(最推荐)
先把两个Activity的ActionBar属性统一,而且都用带android:前缀的写法,避免兼容性问题:
修改Theme.Splash:
<style name="Theme.Splash" parent="@android:style/Theme.NoTitleBar.Fullscreen"> <item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowFullscreen">true</item> <!-- 改成false,和主Activity保持一致 --> <item name="android:windowActionBar">false</item> </style>
修改MainTheme.Base的ActionBar属性为带前缀的版本:
<style name="MainTheme.Base" parent="@android:style/Theme.NoTitleBar.Fullscreen"> <item name="android:windowNoTitle">true</item> <item name="android:windowActionBar">false</item> <!-- 其他属性保持不变 --> </style>
这个方案从根源上解决了主题冲突,大概率能搞定问题。
2. 强制禁用过渡动画
如果方案1无效,直接在启动MainActivity的时候关掉系统默认的过渡动画:
在SplashActivity的StartActivity之后加上这行代码:
StartActivity(typeof(MainActivity)); // 禁用切换动画 OverridePendingTransition(0, 0);
这样不管系统怎么处理,都不会有动画效果,自然也就不会出现缩放了。
3. 延迟启动主Activity
有时候在OnCreate里直接启动主Activity,系统还没完全渲染好启动页,导致切换时动画异常。可以稍微延迟一点再启动:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 延迟100ms启动,给系统足够时间渲染启动页 new Android.OS.Handler().PostDelayed(() => { StartActivity(typeof(MainActivity)); OverridePendingTransition(0, 0); }, 100); }
4. 适配Android 10的全屏主题
如果以上都不行,试试用Android 10推荐的全屏主题写法:
把启动页主题换成MaterialComponents的全屏主题:
<style name="Theme.Splash" parent="Theme.MaterialComponents.NoActionBar.FullScreen"> <item name="android:windowBackground">@drawable/splash_screen</item> <!-- 适配Android 10+的全屏显示 --> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> <item name="android:windowDrawsSystemBarBackgrounds">false</item> </style>
同时主Activity的主题也建议换成MaterialComponents的父主题,保持风格一致。
你先从方案1开始试,这是最可能解决问题的步骤。如果还是不行,再依次尝试后面的方案,应该能解决这个Android 10专属的缩放问题。
内容的提问来源于stack exchange,提问作者Isparia

