본문 바로가기

Learn/Flutter

Flutter SplashScreen/가이드스크린 만들기

 

 

 

  앱을 실행 할 때 화면을 렌더링 할 때 까지의 과정을 매끄럽게 하기 위한 장치

 

https://pub.dev/packages/flutter_native_splash

 

flutter_native_splash | Flutter package

Customize Flutter's default white native splash screen with background color and splash image. Supports dark mode, full screen, and more.

pub.dev

 

pubspec.yaml 파일에 해당 종속성이 추가

dependencies:
  flutter_native_splash: ^2.3.1

 

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

  # IMPORTANT NOTE: These parameter do not affect the configuration of Android 12 and later, which
  # handle splash screens differently that prior versions of Android.  Android 12 and later must be
  # configured specifically in the android_12 section below.

  # 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: "ffffff"
  #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/images/deego_logo_1024.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

  # From Android 12 onwards, the splash screen is handled differently than in previous versions.
  # Please visit https://developer.android.com/guide/topics/ui/splash-screen
  # Following are specific parameters for Android 12+.
  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: true
  #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.png
  #branding_dark_ios: assets/dart_dark-ios.png
  #branding_web: assets/brand-web.gif
  #branding_dark_web: assets/dart_dark-web.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을 적용하기 위해서 아래 명령을 터미널에 순서대로 입력

 

flutter clean
flutter pub get
flutter pub run flutter_native_splash:create

 

 

사용방법은 출처 pub.dev 에 들어가면 더욱 자세하게 볼 수 있다.

 

단지 안드로이드 12이상부터는 사용방법이 바뀌었으니 꼭 참고해야한다.

 

가이드 스크린 만들기

https://pub.dev/packages/shared_preferences

 

shared_preferences | Flutter package

Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android.

pub.dev

 

SharedPreferences를 사용하여 앱이 처음시작했는지 아닌지의 상태를 저장할 필요가 있다.

 

SharedPreferences prefs = await SharedPreferences.getInstance();

// // 앱이 처음 실행되었는지 여부 확인
bool isFirstRun = prefs.getBool('isFirstRun') ?? true;

String initialRoute;
  if (isFirstRun == true) {
    initialRoute = '/'; //스크린가이드 처음부분
   
    prefs.setBool('isFirstRun', false);
  } else {

    initialRoute = '/pages'; // 기존 시작화면
  }

 

로 상태값을 변환하고 라우팅 주소를 다르게 해준 뒤 구성해 놓은 화면을 보여주면 된다.

 


class Explain extends StatelessWidget {
  const Explain({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          color: Colors.white
        ),
        padding: const EdgeInsets.all(10),
        width: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Container(
              child: Container(
                height: MediaQuery.of(context).size.height * 0.7,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    const Text("01",style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24, color: Color(0xFF369BEF))),
                    SizedBox(height: 30),
                    const Text(
                      "다 쓴 페트병, 디고에게 주면",
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22, color: Colors.black),
                    ),
                    SizedBox(height: 10),
                    Text(
                      "보상으로 돌려드립니다.",
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 22, color: Colors.black),
                    ),
                    SizedBox(height: 30),
                    Container(
                      height: MediaQuery.of(context).size.height * 0.4,
                      child: Image.asset(
                        "assets/images/explain_image.png",
                        fit: BoxFit.cover,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
      bottomNavigationBar: ExplainBottom(
        onNextPressed: () async {
          await Navigator.of(context).push(MaterialPageRoute(builder: (context) => ExplainTwo()));
        },
        currentPageIndex: 0,
      ),
    );
  }
}

 

 나와같은 경우는 하단 네비바를 커스텀위젯으로 만들어 재활용하였다. 

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

import '../login.dart';

class ExplainBottom extends StatefulWidget {
  final int currentPageIndex; 
  final Function onNextPressed; 
  const ExplainBottom({super.key, required this.currentPageIndex, required this.onNextPressed});

  @override
  State<ExplainBottom> createState() => _ExplainBottomState();
}

class _ExplainBottomState extends State<ExplainBottom> {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      padding: EdgeInsets.all(10),
      margin: EdgeInsets.all(10),
      // height: MediaQuery.of(context).size.height * 0.08,
      // decoration: BoxDecoration(
      //   border: Border.all(color: Colors.black)
      // ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          TextButton(
            onPressed: ()async{
              await Navigator.of(context).push(MaterialPageRoute(builder: (context) => Log()));
            },
            child: Text("SKIP",
              style: TextStyle(
                  color: Color(0xFF141414),
                  fontWeight: FontWeight.bold,
                  fontSize: 18
              ),
            ),
          ),
          Container(
            // decoration: BoxDecoration(
            //   border: Border.all(color: Colors.black)
            // ),
            width: MediaQuery.of(context).size.width * 0.3,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Circle(widget.currentPageIndex == 0 ? Color(0xFF369BEF) : Color(0xFFD9D9D9)), // 첫번째 페이지면 파란색, 아니면 회색
                Circle(widget.currentPageIndex == 1 ? Color(0xFF369BEF) : Color(0xFFD9D9D9)), // 두번째 페이지면 파란색, 아니면 회색
                Circle(widget.currentPageIndex == 2 ? Color(0xFF369BEF) : Color(0xFFD9D9D9)), // 세번째 페이지면 파란색, 아니면 회색
                Circle(widget.currentPageIndex == 3 ? Color(0xFF369BEF) : Color(0xFFD9D9D9)), // 네번째 페이지면 파란색, 아니면 회색
                Circle(widget.currentPageIndex == 4 ? Color(0xFF369BEF) : Color(0xFFD9D9D9)), // 다번째 페이지면 파란색, 아니면 회색
              ],
            ),
          ),
          TextButton(
            onPressed: (){
              // 다음 페이지로 이동하는 함수 호출
              widget.onNextPressed();
            },
            child: Text("NEXT",
              style: TextStyle(
                  color: Color(0xFF369BEF),
                  fontWeight: FontWeight.bold,
                  fontSize: 18
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Widget Circle(Color color){
  return Container(
    width: 10,
    height: 10, 
    decoration: BoxDecoration(
      shape: BoxShape.circle, 
      color: color, 
    ),
  );
}

'Learn > Flutter' 카테고리의 다른 글

Flutter Provider를 이용한 상태관리  (0) 2024.04.22
Flutter  (0) 2023.08.17