Flutter android and ios splash screen page configuration

1. Conceptual understanding

Splash screen page

1. When you click on the app to start, the page that appears is a splash screen page.
2. Why is there a splash screen? Since the app needs to load code when it starts, this process takes time. You cannot see the real page of the app until the loading is completed. Therefore, when the app is not completely loaded, the system will display a page by default.
3. Usually if this splash screen page is not configured, all you can see is a white screen page or a black screen page. In addition, the program cannot be controlled during the splash screen page, so the pages seen at this stage are static pages.

Start page

1. The startup page is after the splash screen page, and the app is actually loaded. At this time, the program is controllable and is generally used for the display of advertising images or guidance images.
2. A startup page is not necessary. If you do not add a startup page, the homepage will be displayed directly.

2. Display mode

1. Splash screen page

The mainstream app display methods are as follows: in default mode and dark mode respectively.
Teardown of the above page configuration:
The page shown above is a splash screen page, which is mainly divided into two parts, background color + foreground image
Background color: Generally a single color, which can be adapted according to the system theme, such as dark mode.
Foreground image: Generally it is logo icon + text. The pictures are displayed separately, divided into top, middle and bottom, and can be configured appropriately.
Why configure it like this: The method recommended by the program has a relatively high adaptation rate. For example, most Android models can be adapted.

It is not recommended to display an entire image directly

For more information, please read the article: https://zhuanlan.zhihu.com/p/342038493

As shown below: This is the way it is presented on a large screen (pad). It is obvious that the picture has been cropped and part of it is missing.
Why the picture is cropped: Since the picture is displayed on the entire screen and needs to be adapted to different models, the picture will be scaled proportionally, and the excess part will be cropped.

This is why it is not recommended to display an entire picture. Is there any solution? To put it simply, when making a picture, the main content information should not be displayed on the edge of the picture. In this way, even if it is cropped, the main information of the picture will not be lost, and the picture will still look complete.

3. The startup page is as shown below

The picture above is how the startup page is displayed: the startup page is usually for advertising and user guidance. In addition, it can also play a preloading role. For example, if a project has many functions, it will need to load many modules. If a startup page is not added, the user will have to wait too long and the experience will not be good. Of course, you can also display the homepage directly without adding a startup page.

3. Splash screen page configuration

1.android side configuration

Create splash.xml in the drawable directory in project res as follows:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--Splash screen page background color-->
    <item>
        <shape>
            <solid android:color="@color/color_FFFFFF" />
        </shape>
    </item>
    <!--Middle foreground image-->
    <item>
        <bitmap
            android:tint="@color/color_title_bar"
            android:gravity="center"
            android:src="@drawable/ic_splash_center" />

    </item>
    <!--Bottom foreground image-->
    <item android:bottom="@dimen/space_70">
        <bitmap
            android:gravity="bottom"
            android:src="@drawable/ic_splash_bottom" />
    </item>

</layer-list>

Finally introduced in the theme:

    <style name="welcomeTheme" parent="AppTheme">
   
        <item name="android:windowBackground">@drawable/splash</item>
    </style>

This is a common configuration method for Android, but there is a problem here.

Splash screen page configuration on android 12

The theme configuration is as follows:

 implementation "androidx.core:core-splashscreen:1.0.0-beta02"
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="Theme.App" parent="@android:style/Theme.NoTitleBar.Fullscreen">
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    </style>

    <style name="LaunchTheme" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@color/splashScreenBackground</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_icon</item>
        <item name="windowSplashScreenAnimationDuration">2000</item>
        <item name="postSplashScreenTheme">@style/Theme.App</item>
    </style>
    <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
        <item name="android:windowBackground">?android:colorBackground</item>
    </style>
</resources>

The splashscreen_icon file is as follows: it is a small animation

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
  <aapt:attr name="android:drawable">
    <vector
        android:width="108dp"
        android:height="108dp"
        android:viewportHeight="432"
        android:viewportWidth="432">
      <!--
       Scale down the icon and translate if to fit
       within the inner 2/3 (scale <= 0.67) or the viewport.
      -->
      <group
          android:translateX="97"
          android:translateY="97"
          android:scaleX="0.55"
          android:scaleY="0.55">
        <clip-path android:pathData="m322.02,167.89c12.141,-21.437 25.117,-42.497 36.765,-64.158 2.2993,-7.7566 -9.5332,-12.802 -13.555,-5.7796 -12.206,21 .045 -24.375,42.112 -36.567 ,63.166 -57.901,-26.337 -127.00,-26.337 -184.90,0.0 -12.685,-21.446 -24.606,-43.441 -37.743,-64.562 -5.6074,-5.8390 -15.861,1.9202 - 11.747,8.8889 12.030,20.823 24.092,41.629 36.134,62.446C47.866,200.90 5.0987,267.15 0.0,337.5c144.00,0.0 288.00,0.0 432.0,0.0C426.74,267.06 384.46,201.32 322.02,167. 89ZM116.66,276.03c-13.076,0.58968 -22.531,-15.277 -15.773,-26.469 5.7191,-11.755 24.196,-12.482 30.824,-1.2128 7.8705,11.451 -1.1102,28.027 -15.051,27.682zM315.55,276.03c-13.076,0.58968 -22.53 1,-15.277 -15.773,-26.469 5.7191,-11.755 24.196,-12.482 30.824 ,-1.2128 7.8705,11.451 -1.1097,28.027 -15.051,27.682z" />
        <path
            android:fillColor="#3ddc84"
            android:pathData="m322.02,167.89c12.141,-21.437 25.117,-42.497 36.765,-64.158 2.2993,-7.7566 -9.5332,-12.802 -13.555,-5.7796 -12.206,21.045 -24.375,42.112 -36.567,63.166 -57.901 ,-26.337 -127.00,-26.337 -184.90,0.0 -12.685,-21.446 -24.606,-43.441 -37.743,-64.562 -5.6074,-5.8390 -15.861,1.9202 -11.747,8.8889 12.030,20.823 24.092,41.629 36.134,62.446C47 .866,200.90 5.0987,267.15 0.0,337.5c144.00,0.0 288.00,0.0 432.0,0.0C426.74,267.06 384.46,201.32 322.02,167.89ZM116.66,276.0 3c-13.076,0.58968 -22.531,-15.277 -15.773,-26.469 5.7191,-11.755 24.196,-12.482 30.824,-1.2128 7.8705,11.451 -1.1102,28.027 -15.051,27.682zM315.55,276.03c-13.076,0.58968 -22.531,-15.277 -15.77 3,-26.469 5.7191,-11.755 24.196,-12.482 30.824,-1.2128 7.8705 ,11.451 -1.1097,28.027 -15.051,27.682z"
            android:strokeWidth="1.93078" />
        <group android:name="anim">
          <path
              android:fillAlpha="0.999"
              android:fillColor="#979797"
              android:fillType="nonZero"
              android:pathData="m-197.42,638.59c0.0,0.0 -5.9627,-259.30 46.113,-215.87 32.895,27.437 76.838,-65.597 91.553,-46.592 2.7119,-7.7182 95.04 5,109.16 139.74,17.953 10.678,-21.792 43.788 ,-64.489 78.236,-16.164 54.226,76.069 110.90,-100.75 179.84,-17.966 36.393,43.701 96.377,-23.605 148.05,19.889 42.614,35.86 9 83.166,3.7255 109.76,61.101 24.321,52.465 35.893,197.64 35.893,197.64L631.77, 92.867L-197.42,92.867Z"
              android:strokeAlpha="1"
              android:strokeColor="#00000000"
              android:strokeWidth="12" />
        </group>
      </group>
    </vector>
  </aapt:attr>

  <target android:name="anim">
    <aapt:attr name="android:animation">
      <objectAnimator
          android:duration="1000"
          android:propertyName="translateY"
          android:repeatCount="0"
          android:valueFrom="0"
          android:valueTo="-432"
          android:valueType="floatType"
          android:interpolator="@android:interpolator/accelerate_decelerate" />
    </aapt:attr>
  </target>
  <target android:name="anim">
    <aapt:attr name="android:animation">
      <objectAnimator
          android:duration="500"
          android:propertyName="translateX"
          android:repeatCount="-1"
          android:repeatMode="reverse"
          android:valueFrom="-162"
          android:valueTo="162"
          android:valueType="floatType"
          android:interpolator="@android:interpolator/accelerate_decelerate" />
    </aapt:attr>
  </target>
</animated-vector>

Referenced in AndroidManifest

 <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme"
                />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

2.ios configuration

Regarding the configuration on the ios side, it is relatively simple. Using the Xcode tool, there is no need to write code.

Set Icon

Open Assets.xcassets and pull the image in the project structure into the corresponding position in AppIcon, as shown in the figure below. Finally, set the App Icons Source to AppIcon in your xcodeproj, and then build again.

Set Launch Screen

In my current version of Xcode (13.0), setting up a launch screen requires a Launch Screen File, which actually works with .storyboard.

We create a .storyboard file in the project, I named it “Launch Screen.storyboard”.

Open our storyboard and design in it.

Finally, set the Launch Screen File to “Launch Screen.storyboard” in our xcodeproj.

This is done.