How to prevent background from distorting when using Syncaidius' Android Load Screen Workaround

We are using Monogame version 3.8.1.303, and experienced the problem in open ticket Black screen instead of splash screen #5899. The workaround Syncaidius posted worked great when loading on an Android tablet and a Kindle Fire.

However, this solution will not honor the aspect ratio of the image and several Android devices have differing aspect ratios. Is there a way to stretch/shrink the image to fill the window best possible without distorting it by changing the aspect ratio?

I’ll caveat below with I am very inexperienced with Android development.

Below is code that I found in (Android: Scale a Drawable or background image? - Stack Overflow). The command android:scaleType=“fitXY” seems to be what I want.

<FrameLayout  
android:layout_width="fill_parent" android:layout_height="fill_parent">

  <ImageView 
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:src="@drawable/back" android:scaleType="fitXY" />

  <LinearLayout>your views</LinearLayout>
</FrameLayout>

However, I am struggling to somehow adapt this to fit in with Syncaidus’s sample.

Here is my Styles.xml file:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="SplashTheme" parent="android:Theme">
    <item name="android:windowBackground">@drawable/splash</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowContentOverlay">@null</item>
  </style>
  <declare-styleable name="SplashStyle" >
    <attr name="android:scaleType">fitXY</attr>
  </declare-styleable>
</resources>

Below is how I am calling the background screen. My strategy way to set the styleable SplashStyle to the ImageView (not sure this is actually a valid strategy). I think the line stating splashView = new ImageView(ApplicationContext); is where my issue is. There are a couple of overloads for ImageView’s constructor that allow IAttributesSet, but I can’t square the relationship between ImageView’s constructor choices with somehow passing in the SplashStyle. Again, this approach may just be incorrect.

   private FrameLayout layout;
   private View splashView;

   protected override void OnCreate(Bundle bundle)
   {
       base.OnCreate(bundle);
  
       game = new CircuitSnapGameAndroid();
       game.OnLoadingContent += HandleOnLoadingContent;

       layout = new FrameLayout(ApplicationContext);
       layout.AddView((View)game.Services.GetService(typeof(View)));

       // Use the splash screen image to cover up the black/blank screen while Android/MonoGame finish initializing.
       // thanks Syncaidius https://github.com/MonoGame/MonoGame/issues/5899#issuecomment-326251089
       int id = Resources.GetIdentifier("splash", "drawable", PackageName);

       splashView = new ImageView(ApplicationContext);
       splashView.SetBackgroundResource(id);
       
       layout.AddView(splashView);

       SetContentView(layout);
       game.Run();
   }

An alternate approach that might work well would be just to center a splash screen graphic. As long as the graphics’ size is smaller than the resolution of most screens, this would probably work ok. It seems like the default behavior for windowBackground is to scale it, so would need to figure out in this case how to override this behavior and just center instead of scaling the background.

Any help is appreciated. Thank you!

-Brett

<attr name="android:scaleType">fitXY</attr>
The fitXY stretches the image.

Use CENTER_INSIDE instead to get uniform scaling best fit centered.

I am not sure about the case or underscore when used in the style XML. But this should lead to the solution.

Ah excellent, CENTER_INSIDE works well. Just had to insert the line <item name="android:scaleType">centerInside</item> into the style and everything worked well. Thank you for the assistance @stromkos.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="SplashTheme" parent="android:Theme">
    <item name="android:windowBackground">@drawable/splash</item>
    <item name="android:scaleType">centerInside</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowContentOverlay">@null</item>
  </style>
</resources>