라티의 작은 일기장

패스트캠퍼스 환급챌린지 19일차 미션(2월 19일): 15개 프로젝트로 실무까지 끝내는 Dart & Flutter 앱 개발 강의 후기 본문

Flutter & Dart

패스트캠퍼스 환급챌린지 19일차 미션(2월 19일): 15개 프로젝트로 실무까지 끝내는 Dart & Flutter 앱 개발 강의 후기

코드라티 2024. 2. 19. 23:39

 

오늘은 토스 앱 클론 파트로 들어가는 첫번째 날이다. 시작에 앞서 강사님이 빠른 플러터 앱 개발을 위한 Fast App Base 프로젝트에 대해 간단하게 소개를 해주셨다. 일종의 스타터 프로젝트로, 앱 구성에 필수적인 위젯들이 이미 구현돼있고, 국제화와 다크모드 등의 설정 또한 편리하게 변경 또는 추가할 수 있도록 되어있는 친절한 프로젝트라고 할 수 있다.

 

일단 준비해주신 아이콘을 활용해 간단하게 스플래시 화면부터 구현해보았다.

flutter_native_splash 패키지가 이미 적용돼있어서 그냥 설정값만 바꿔주면 되었다.

손쉽게 적용되었다!

그런데 이걸로 끝은 아닌게, 앱 내부에서 만약 로그인 처리를 위해 별도의 스플래시 화면을 보여줄 필요가 있거나 하는 상황이면 flutter 엔진 내부에서도 이 스플래시 화면이 필요해진다고 한다. 아직 잘 와닿지는 않지만 일단 별도의 스플래시 화면을 추가해주자.

 

s_splash.dart에 스플래시 화면을 구현하고, 1.5초 뒤에 메인 화면으로 이동하는 코드를 작성해주었다.

// ...

class _SplashScreenState extends State<SplashScreen> {
  @override
  void initState() {
    delay(() {
      Nav.clearAllAndPush(const MainScreen());
    }, 1500.ms);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
        child: Image.asset(
      "assets/image/splash/splash.png",
      width: 192,
      height: 192,
    ));
  }
}

 

delay로 감싼 덕분에 위처럼 initState 함수 안에서 화면 전환을 해도 잘 실행되는 것 처럼 보이지만, delay를 제거하면 곧바로 아래와 같이 앱이 Crash나는 것을 볼 수 있다.

initState 함수에서는 값의 변경 정도의 작업만 이루어지는게 좋고, 화면 전환과 같은 코드는 AfterLayoutMixin에서 관리해주는게 좋다고 한다.

@override
  FutureOr<void> afterFirstLayout(BuildContext context) {
    Nav.clearAllAndPush(const MainScreen());
  }

 

 

그런데 이렇게 해도 스플래시가 네이티브 스플래시와의 전환에서 Flicker + Layout Shift가 발생하는 것이 보인다.

자연스럽게 이어지게 하는 방법은 없을까?

 

일단 이 임의의 스플래시 화면을 담당하는 파일을 다시 지워주고(!!), 사용과 참조를 하는 코드를 다시 원복한 뒤, main.dart에 아래와 같이 코드를 추가해주자.

import 'package:flutter_native_splash/flutter_native_splash.dart';

void main() async {
  final bindings = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: bindings);
// ...

이렇게하면 FlutterNativeSplash 내부에서 기존의 화면을 유지시켜준다고 한다. 이걸 우리가 원하는 특정 시점에 지워주면 된다.

 

  @override
  FutureOr<void> afterFirstLayout(BuildContext context) {
    delay(() {
      FlutterNativeSplash.remove();
    },1500.ms);
  }

 

지금은 이렇게 delay를 걸어뒀지만 로그인 처리라던가 기타 로딩 이후에 Flutter Native Splash를 지워주는 처리를 해주면 되는것이다.

물론 이게 스플래시 화면 처리의 정답은 아니고, 상황에 따라 더 적합한 스플래시 처리 방법이 있을 수 있다.

 

강의 난의도가 갑자기 확 올라간 느낌이다 ㄷㄷ

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

https://bit.ly/48sS29N