Flutter 앱에서 앱 아이콘과 실행 화면을 어떻게 수정하나요?

질문

Flutter 앱의 아이콘과 실행 화면(스플래시 스크린)을 어떻게 수정하고 맞춤설정할 수 있나요?

답변

Flutter 앱의 아이콘과 스플래시 스크린은 사용자가 앱을 식별하고 브랜드 가치를 전달하는 중요한 요소입니다. 각 플랫폼(iOS, Android)마다 설정 방식이 다르기 때문에 모든 플랫폼에서 올바르게 표시되도록 구성하는 방법을 알아보겠습니다.

1. 앱 아이콘 변경하기

1.1 Flutter 패키지를 사용한 간편한 방법

가장 쉬운 방법은 flutter_launcher_icons 패키지를 사용하는 것입니다:

# pubspec.yaml
dev_dependencies:
  flutter_launcher_icons: ^0.13.1

flutter_launcher_icons:
  android: "launcher_icon"
  ios: true
  image_path: "assets/icons/icon.png"
  min_sdk_android: 21 # Android min SDK 버전
  web:
    generate: true
    image_path: "assets/icons/icon.png"
  windows:
    generate: true
    image_path: "assets/icons/icon.png"
  macos:
    generate: true
    image_path: "assets/icons/icon.png"

설정 후 아래 명령어를 실행합니다:

# 앱 아이콘 생성 명령어
flutter pub get
flutter pub run flutter_launcher_icons

1.2 Android 앱 아이콘 수동 설정

  1. 여러 해상도에 맞는 아이콘 파일 준비:
해상도 폴더명 크기
mdpi android/app/src/main/res/mipmap-mdpi 48x48
hdpi android/app/src/main/res/mipmap-hdpi 72x72
xhdpi android/app/src/main/res/mipmap-xhdpi 96x96
xxhdpi android/app/src/main/res/mipmap-xxhdpi 144x144
xxxhdpi android/app/src/main/res/mipmap-xxxhdpi 192x192
  1. 각 해상도 폴더에 ic_launcher.png 파일을 넣습니다.

  2. Android 적응형 아이콘 설정(API 26 이상):

<!-- android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml -->
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@color/ic_launcher_background"/>
    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

1.3 iOS 앱 아이콘 수동 설정

  1. iOS 아이콘 에셋을 준비합니다:
이름 크기
Icon-App-20x20@1x.png 20x20
Icon-App-20x20@2x.png 40x40
Icon-App-20x20@3x.png 60x60
Icon-App-29x29@1x.png 29x29
Icon-App-29x29@2x.png 58x58
Icon-App-29x29@3x.png 87x87
Icon-App-40x40@1x.png 40x40
Icon-App-40x40@2x.png 80x80
Icon-App-40x40@3x.png 120x120
Icon-App-60x60@2x.png 120x120
Icon-App-60x60@3x.png 180x180
Icon-App-76x76@1x.png 76x76
Icon-App-76x76@2x.png 152x152
Icon-App-83.5x83.5@2x.png 167x167
Icon-App-1024x1024@1x.png 1024x1024
  1. 위 파일들을 ios/Runner/Assets.xcassets/AppIcon.appiconset/ 디렉토리에 넣습니다.

  2. Contents.json 파일을 구성합니다:

{
  "images": [
    {
      "size": "20x20",
      "idiom": "iphone",
      "filename": "Icon-App-20x20@2x.png",
      "scale": "2x"
    },
    {
      "size": "20x20",
      "idiom": "iphone",
      "filename": "Icon-App-20x20@3x.png",
      "scale": "3x"
    }
    // 나머지 항목들...
  ],
  "info": {
    "version": 1,
    "author": "xcode"
  }
}

2. 스플래시 스크린 설정하기

2.1 flutter_native_splash 패키지 사용

가장 편리한 방법은 flutter_native_splash 패키지를 사용하는 것입니다:

# pubspec.yaml
dev_dependencies:
  flutter_native_splash: ^2.3.2

flutter_native_splash:
  color: "#42a5f5"
  image: assets/splash.png
  color_dark: "#121212"
  image_dark: assets/splash_dark.png

  android_12:
    image: assets/splash_android12.png
    icon_background_color: "#42a5f5"

  web: false
  fullscreen: true

설정 후 아래 명령어를 실행합니다:

flutter pub get
flutter pub run flutter_native_splash:create

2.2 Android 스플래시 스크린 수동 설정

Android 11 이하:

  1. android/app/src/main/res/drawable/launch_background.xml 파일을 수정합니다:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/white" />
    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/splash" />
    </item>
</layer-list>
  1. splash.png 이미지를 적절한 해상도로 android/app/src/main/res/mipmap-* 폴더에 추가합니다.

Android 12 이상 (스플래시 화면 API):

  1. android/app/src/main/res/values-v31/styles.xml 파일을 생성/수정합니다:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
        <item name="android:windowSplashScreenBackground">@color/splash_background</item>
        <item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_splash</item>
        <item name="android:windowSplashScreenIconBackgroundColor">@color/splash_icon_background</item>
        <item name="android:windowSplashScreenBrandingImage">@drawable/splash_branding</item>
    </style>
</resources>
  1. 필요한 색상을 android/app/src/main/res/values/colors.xml에 정의합니다:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="splash_background">#FFFFFF</color>
    <color name="splash_icon_background">#42a5f5</color>
</resources>

2.3 iOS 스플래시 스크린 수동 설정

  1. Xcode로 ios/Runner.xcworkspace를 엽니다.

  2. Assets.xcassets에 새 Image Set을 추가하고 이름을 'LaunchImage'로 지정합니다.

  3. 다양한 크기의 스플래시 이미지를 추가합니다:

    • 1x: 320x480px
    • 2x: 640x960px
    • 3x: 1242x2208px
  4. LaunchScreen.storyboard 파일을 수정합니다:

    • 이미지 뷰를 추가하고 앞에서 만든 'LaunchImage'로 지정
    • 제약 조건을 설정하여 이미지를 화면 중앙에 배치

또는 간단히 색상과 텍스트만 포함된 스플래시 화면을 만들 수 있습니다:

<!-- ios/Runner/Base.lproj/LaunchScreen.storyboard -->
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <device id="retina6_1" orientation="portrait" appearance="light"/>
    <!-- 기타 설정... -->
    <scenes>
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="thr-yb-z6n">
                                <rect key="frame" x="157" y="398" width="100" height="100"/>
                                <constraints>
                                    <constraint firstAttribute="width" constant="100" id="V7S-Ub-5yf"/>
                                    <constraint firstAttribute="height" constant="100" id="tYP-nG-hMG"/>
                                </constraints>
                            </imageView>
                        </subviews>
                        <viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
                        <color key="backgroundColor" red="0.25882352941176473" green="0.6470588235294118" blue="0.9607843137254902" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="thr-yb-z6n" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="Fgs-7g-pYE"/>
                            <constraint firstItem="thr-yb-z6n" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="TQA-XW-tK5"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
    <resources>
        <image name="LaunchImage" width="100" height="100"/>
    </resources>
</document>

3. 애니메이션이 있는 스플래시 스크린 구현

네이티브 스플래시 스크린은 일반적으로 정적이지만, Flutter 앱이 로드된 후 애니메이션이 있는 스플래시 화면을 추가로 표시할 수 있습니다:

import 'package:flutter/material.dart';

class AnimatedSplashScreen extends StatefulWidget {
  final Widget nextScreen;

  const AnimatedSplashScreen({Key? key, required this.nextScreen}) : super(key: key);

  @override
  _AnimatedSplashScreenState createState() => _AnimatedSplashScreenState();
}

class _AnimatedSplashScreenState extends State<AnimatedSplashScreen>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );
    _animation = CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    );

    _controller.forward();

    Future.delayed(const Duration(seconds: 3), () {
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(builder: (context) => widget.nextScreen),
      );
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: Center(
        child: ScaleTransition(
          scale: _animation,
          child: const FlutterLogo(size: 200),
        ),
      ),
    );
  }
}

// 사용 예시
void main() {
  runApp(
    MaterialApp(
      home: AnimatedSplashScreen(
        nextScreen: HomeScreen(),
      ),
      debugShowCheckedModeBanner: false,
    ),
  );
}

4. 앱 이름 변경하기

앱 아이콘과 함께 앱 이름도 수정하는 방법을 알아보겠습니다:

4.1 Android 앱 이름 변경

android/app/src/main/AndroidManifest.xml 파일에서:

<application
    android:label="앱 이름"
    android:icon="@mipmap/ic_launcher">
    <!-- 기타 설정... -->
</application>

4.2 iOS 앱 이름 변경

ios/Runner/Info.plist 파일에서:

<key>CFBundleName</key>
<string>앱 이름</string>
<key>CFBundleDisplayName</key>
<string>앱 이름</string>

5. 모범 사례 및 팁

5.1 아이콘 디자인 팁

  • 모든 플랫폼에서 인식할 수 있도록 단순하고 명확한 아이콘 디자인
  • 아이콘 배경에는 알파 채널(투명도) 사용 피하기
  • 최소 1024x1024px 해상도로 원본 이미지 준비
  • 각 플랫폼의 디자인 가이드라인 준수
    • Android: Material Design 아이콘 가이드라인
    • iOS: Human Interface Guidelines

5.2 스플래시 스크린 최적화

  • 스플래시 스크린은 가능한 간단하게 유지하여 앱 로딩 시간 최소화
  • 브랜드 로고나 앱 아이콘만 표시하여 일관성 유지
  • 다크 모드 대응 버전도 준비
  • 앱이 빠르게 로드되도록 초기화 코드 최적화
// main.dart에서 비동기 초기화 작업 최적화
void main() async {
  // Flutter 엔진이 바인딩되었는지 확인
  WidgetsFlutterBinding.ensureInitialized();

  // 필요한 초기화 작업 병렬 처리
  await Future.wait([
    _initializeFirebase(),
    _loadPreferences(),
    _preloadCriticalAssets(),
  ]);

  runApp(MyApp());
}

5.3 접근성 고려사항

  • 앱 아이콘과 스플래시 스크린의 색상 대비가 충분한지 확인
  • 브랜드 이미지를 텍스트 대신 사용하여 국제화 문제 해결
  • 특정 기기나 화면 크기에서 스플래시 스크린이 왜곡되지 않도록 확인

결론

Flutter 앱의 아이콘과 실행 화면을 수정하는 것은 앱의 브랜딩과 사용자 경험에 중요한 요소입니다. 전문적인 이미지를 제공하기 위해 여러 해상도의 에셋을 준비하고, 각 플랫폼의 요구사항을 충족시키는 것이 중요합니다.

flutter_launcher_iconsflutter_native_splash 같은 패키지를 사용하면 이 과정을 크게 간소화할 수 있으며, 수동으로 설정하는 방법도 알아두면 더 세밀한 커스터마이징이 가능합니다.

앱 아이콘과 스플래시 스크린은 사용자가 앱을 처음 접할 때 보게 되는 요소이므로, 브랜드 아이덴티티를 효과적으로 전달하고 앱의 전반적인 품질을 나타내는 데 중요한 역할을 합니다.

results matching ""

    No results matching ""