🙊 문제인식
- flutter의 작동방식 상 시작 시 화면이 매끄럽지 않다는 것을 체감할 수 있다.
- 이를 해결 하기 위해서는 flutter가 화면을 렌더링 하기 전까지 splash screen을 보여주면 된다.
https://pub.dev/packages/flutter_native_splash
flutter_native_splash package를 다운 받는다. 그렇다면 pubspec.yaml 파일에 해당 종속성이 추가 된다.
dependencies:
flutter_native_splash: ^2.3.1
pubspec.yaml에 아래 코드를 추가 혹은 lib 디렉토리에 flutter_native_splash.yaml 파일을 만든 후 아래 코드를 추가한다.
flutter_native_splash:
# This package generates native code to customize Flutter's default white native splash screen
# with background color and splash image.
# Customize the parameters below, and run the following command in the terminal:
# dart run flutter_native_splash:create
# To restore Flutter's default white splash screen, run the following command in the terminal:
# dart run flutter_native_splash:remove
# color or background_image is the only required parameter. Use color to set the background
# of your splash screen to a solid color. Use background_image to set the background of your
# splash screen to a png image. This is useful for gradients. The image will be stretch to the
# size of the app. Only one parameter can be used, color and background_image cannot both be set.
color: "#42a5f5"
#background_image: "assets/background.png"
# Optional parameters are listed below. To enable a parameter, uncomment the line by removing
# the leading # character.
# The image parameter allows you to specify an image used in the splash screen. It must be a
# png file and should be sized for 4x pixel density.
#image: assets/splash.png
# The branding property allows you to specify an image used as branding in the splash screen.
# It must be a png file. It is supported for Android, iOS and the Web. For Android 12,
# see the Android 12 section below.
#branding: assets/dart.png
# To position the branding image at the bottom of the screen you can use bottom, bottomRight,
# and bottomLeft. The default values is bottom if not specified or specified something else.
#branding_mode: bottom
# The color_dark, background_image_dark, image_dark, branding_dark are parameters that set the background
# and image when the device is in dark mode. If they are not specified, the app will use the
# parameters from above. If the image_dark parameter is specified, color_dark or
# background_image_dark must be specified. color_dark and background_image_dark cannot both be
# set.
#color_dark: "#042a49"
#background_image_dark: "assets/dark-background.png"
#image_dark: assets/splash-invert.png
#branding_dark: assets/dart_dark.png
# Android 12 handles the splash screen differently than previous versions. Please visit
# https://developer.android.com/guide/topics/ui/splash-screen
# Following are Android 12 specific parameter.
android_12:
# The image parameter sets the splash screen icon image. If this parameter is not specified,
# the app's launcher icon will be used instead.
# Please note that the splash screen will be clipped to a circle on the center of the screen.
# App icon with an icon background: This should be 960×960 pixels, and fit within a circle
# 640 pixels in diameter.
# App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
# 768 pixels in diameter.
#image: assets/android12splash.png
# Splash screen background color.
#color: "#42a5f5"
# App icon background color.
#icon_background_color: "#111111"
# The branding property allows you to specify an image used as branding in the splash screen.
#branding: assets/dart.png
# The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
# apply when the device is in dark mode. If they are not specified, the app will use the
# parameters from above.
#image_dark: assets/android12splash-invert.png
#color_dark: "#042a49"
#icon_background_color_dark: "#eeeeee"
# The android, ios and web parameters can be used to disable generating a splash screen on a given
# platform.
#android: false
#ios: false
#web: false
# Platform specific images can be specified with the following parameters, which will override
# the respective parameter. You may specify all, selected, or none of these parameters:
#color_android: "#42a5f5"
#color_dark_android: "#042a49"
#color_ios: "#42a5f5"
#color_dark_ios: "#042a49"
#color_web: "#42a5f5"
#color_dark_web: "#042a49"
#image_android: assets/splash-android.png
#image_dark_android: assets/splash-invert-android.png
#image_ios: assets/splash-ios.png
#image_dark_ios: assets/splash-invert-ios.png
#image_web: assets/splash-web.gif
#image_dark_web: assets/splash-invert-web.gif
#background_image_android: "assets/background-android.png"
#background_image_dark_android: "assets/dark-background-android.png"
#background_image_ios: "assets/background-ios.png"
#background_image_dark_ios: "assets/dark-background-ios.png"
#background_image_web: "assets/background-web.png"
#background_image_dark_web: "assets/dark-background-web.png"
#branding_android: assets/brand-android.png
#branding_dark_android: assets/dart_dark-android.png
#branding_ios: assets/brand-ios.gif
#branding_dark_ios: assets/dart_dark-ios.gif
# The position of the splash image can be set with android_gravity, ios_content_mode, and
# web_image_mode parameters. All default to center.
#
# android_gravity can be one of the following Android Gravity (see
# https://developer.android.com/reference/android/view/Gravity): bottom, center,
# center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal,
# fill_vertical, left, right, start, or top.
#android_gravity: center
#
# ios_content_mode can be one of the following iOS UIView.ContentMode (see
# https://developer.apple.com/documentation/uikit/uiview/contentmode): scaleToFill,
# scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight,
# bottomLeft, or bottomRight.
#ios_content_mode: center
#
# web_image_mode can be one of the following modes: center, contain, stretch, and cover.
#web_image_mode: center
# The screen orientation can be set in Android with the android_screen_orientation parameter.
# Valid parameters can be found here:
# https://developer.android.com/guide/topics/manifest/activity-element#screen
#android_screen_orientation: sensorLandscape
# To hide the notification bar, use the fullscreen parameter. Has no effect in web since web
# has no notification bar. Defaults to false.
# NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
# To show the notification bar, add the following code to your Flutter app:
# WidgetsFlutterBinding.ensureInitialized();
# SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top], );
#fullscreen: true
# If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
# with the info_plist_files parameter. Remove only the # characters in the three lines below,
# do not remove any spaces:
#info_plist_files:
# - 'ios/Runner/Info-Debug.plist'
# - 'ios/Runner/Info-Release.plist'
이때, splash screen에 추가 할 내용이 많지 않다면 새로운 yaml 파일을 만드는 것보다 pubspec.yaml에 바로 추가하는 것이 좋은 선택지 일 수도 있다. 해당 방식에 대해서 조금 더 설명하자면, 아래 코드 처럼 수정해주면 된다.
(이때, 들여쓰기가 상당히 중요하니 유의하자!!)
dev_dependencies:
flutter_native_splash: ^2.3.1
flutter_native_splash:
...
# your splash screen
# color : "#42a5f5"
...
이제 수정한 splash screen을 적용하기 위해서 아래 명령을 터미널에 입력한다.
flutter clean
flutter pub get
flutter pub run flutter_native_splash:create
혹은 파일 경로를 지정하려면 아래 코드를 입력한다.
flutter clean
flutter pub get
flutter pub run flutter_native_splash:create --path=path/to/my/file.yaml
import 'package:flutter_native_splash/flutter_native_splash.dart';
void main() {
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
runApp(const MyApp());
}
// whenever your initialization is completed, remove the splash screen:
FlutterNativeSplash.remove();
위의 코드는 기본적으로 package에서 제공되는 예시이다.
FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding) 를 사용하면, 첫 프레임을 flutter에서 렌더링 하더라도 splash screen을 없애지 않는다.
앱 시작 전 원하는 행위 (http request)등을 끝낸 후 FlutterNativeSplash.remove();를 사용하여 스플래시 화면을 없앨 수 있다.
새로 splash screen을 설정 할 때에는 android/app/main/res 디렉토리에서 drawable 관련 파일들을 모두 삭제하고 다시 screen을 설정 하거나
flutter pub run flutter_native_splash:remove
명령을 터미널에 실행 한 후 재설정 해준다.
또한, 안드로이드 12로 업데이트 되면서 splash 화면이 기본 앱 아이콘으로 고정이 되어 버렸다.. 그래서 이를 native_splash_screen package에서 지원 하니, flutter_native_splash.yaml 파일에서 android 12항목에 추가로 splash screen을 설정해주면 된다.