3

I am working on getting a splash activity implemented in my project. The splash activity currently loads perfectly, and there's no "white flash" before the image loads - which is good.

My only problem is maintaining the correct aspect ratio of the splash screen image.

Here's the theme I am using for SplashActivity

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/splash</item>
</style>

splash.xml

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
        android:src="@drawable/pink_grid"
        android:gravity="fill_vertical|clip_horizontal"
/>

And here's a screenshot of the result I am getting:

Improper Aspect Ratio

The black / pink grid image that I am using as the background has uniform squares. As you can see from the image, it's not maintaining a proper aspect ratio (being squished horizontally).

Here's the grid image (1280x1920):

Pink and black grid image

What I tried:

It seems the only way to control the aspect ratio of the splash windowBackground is by using gravity. I tried to fill the image vertically and crop horizontally. But this does not maintain aspect ratio.

How can I adjust the gravity of the splash image to maintain aspect ratio and fit the screen on any device?

Edit: Progress based on Raz's answer:

activity_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/pink_grid" android:scaleType="centerCrop"/>
</merge>

SplashActivity.kt

class SplashActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

//        val intent = Intent(this, MainActivity::class.java)
//        startActivity(intent)
//        finish()
    }
}

AndroidManifest.xml

<application>
    <!-- ... -->
    <activity
            android:name=".SplashActivity"
            android:theme="@style/SplashTheme">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

styles.xml

<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

The splash screen is just a black screen now. The pink / black grid is not showing up.

Joe
  • 3,772
  • 3
  • 33
  • 64
  • i am at the same situation as you were. did you solve it? if yes then please let me know. – Tara Nov 14 '20 at 19:57

3 Answers3

0

AFAIK, windowBackground will always fill the screen. What you need to do is:

Set the layout of the activity to:

<FrameLayout 
        android:width="match_parent" 
        android:height="match_parent">
    <ImageView  
android:width="match_parent"  
android:height="match_parent"  
android:ScaleType="CENTER_CROP"  android:src="your_image"/>
        </FrameLayout>

The imageView property scaletype will preserve the aspect ratio.

As optimizations:

  1. Set windowBackground as transparent (for reducing overdraw)
  2. Change the root FrameLayout to <merge> - like so:

<merge> <ImageView
android:width="match_parent"
android:height="match_parent"
android:ScaleType="CENTER_CROP" android:src="your_image"/> </merge>

Raz
  • 8,918
  • 3
  • 27
  • 40
  • I set the windowBackground as transparent @android:color/transparent. I don't know what you mean by #2. Can you post some XML? – Joe Jul 07 '19 at 20:54
  • Sorry, I'm on my phone so can't write any code but you can look at this. https://stackoverflow.com/questions/8834898/what-is-the-purpose-of-androids-merge-tag-in-xml-layouts – Raz Jul 07 '19 at 20:56
  • It's more for optimization actually. You can set a framelayout all the same – Raz Jul 07 '19 at 20:57
  • I'm not sure how is relevant to my question. – Joe Jul 08 '19 at 14:43
  • @Joe, I edited my answer. Hopefully it's more understandable now. – Raz Jul 09 '19 at 06:11
  • Thanks, but it does not work. I've edited my original question to show all the progress I've made with your answer. The launch screen is simply a black screen now. No image is showing up. – Joe Jul 09 '19 at 20:05
  • You are switching to the next activity immediately on the oncreate. This will not show the splash screen. Remove those lines. Also, you need to setContentView(your_layout_id) – Raz Jul 10 '19 at 05:48
  • I added setContentView, and commented out the intent. The splash screen now properly loads on app load in the correct aspect ratio... however it never transitions to main activity. It just stays on the splash screen. – Joe Jul 10 '19 at 15:51
  • Yes. Usually in a splash screen you need to add a timer or based on some event to call the next activity (the code you commented out) – Raz Jul 10 '19 at 16:10
  • I appreciate your help, but adding a timer is not a valid solution here. Splash screens should be an aesthetic visual for as quick as possible when the app first loads into memory. I think my solution here may be to create multiple splash screens based on pixel density. – Joe Jul 10 '19 at 21:09
  • Not sure how that's relevant but OK. That's beyond the scope of question. – Raz Jul 10 '19 at 21:19
0

When using vector drawable the following works great:

drawable/splash.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:gravity="center" android:drawable="@drawable/ic_launcher_foreground"/>
</layer-list>
Slion
  • 2,558
  • 2
  • 23
  • 27
0

For those who land on this page but couldn't find an answer:

Here is a solution.

Basically, you need to change the src from the raw "png/jpg/..." to xml, and the xml imports the raw image with setting android:gravity="center".

Josh Liu
  • 374
  • 1
  • 2
  • 12