본문 바로가기
flutter

[플러터]Flutter / 아주 쉬운 왕초보 Splash화면 만들기(패키지 필요 없음)(인트로 화면 만들기)

by ch5c 2024. 9. 10.
반응형

대부분의 앱들은 시작 시에 짧은 Splash 화면을 가진다. 

이번 포스트에서는 ui 구성만으로 초간단 스플래시 화면을 만들어 볼 것이다.

다른 대부분의 사람들은 flutter_native_splash 패키지를 이용해서 만들지만 이번 포스트는 그런 작업보다 더 간단하다.

 

일단 먼저 결과물을 살펴보자.

 

전체 코드는 이렇다.

import 'package:flutter/material.dart';

class IntroBlog extends StatefulWidget {
  const IntroBlog({super.key});

  @override
  State<IntroBlog> createState() => _IntroBlogState();
}

class _IntroBlogState extends State<IntroBlog> {

  bool canShowSplash = true;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
      setState(() {
        canShowSplash = false;
      });
      await Future.delayed(Duration(seconds: 3));
      Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) {
        return Scaffold();
      },));
    },);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Center(
            child: AnimatedOpacity(
              duration: Duration(seconds: 2),
              opacity: canShowSplash ? 0 : 1,
              child: Image.asset('assets/IMG_3467.jpg', width: 300,),
            ),
          ),
          Text('스플래시 예시', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 30))
        ],
      ),
    );
  }
}

 

이 코드에서 봐야 할것은 5가지 정도이다.

첫 번째는StatefulWidget

 

StatefulWidget은 화면이 변화할 때 써줘야 하는 코드인데 이 스플래시 화면은 화면이 변하니 써주는 것이다.

두 번째는 bool canShowSplash = true;

 

이 코드의 핵심이다. 이렇게 선언한 불리언 값으로 애니메이션을 동작할지 하지 않을지 결정한다.

세 번째는 void initState()

 

이니스테이트를 사용함으로써 이 화면이 시작될 때 선언한 불리언값을 바꿔줄 수 있다.

네 번째는 AnimatedOpacity()

 

오파시티, 즉 투명도를 조종하는 애니메이션 위젯으로 사진이 서서히 나타는 효과를 줄 수 있다.

다섯 번째는 opacity: canShowSplash ? 0 : 1

 

애니메이티드오파시티의 하위 값으로 오파시티를 조종하는 값인데 거기에 만들어둔 불리언 값을 넣어 true일 때엔 안 보이고 false 일 때는 보이게 해 준다.

코드 설명

이렇게 다섯 개를 간추려서 정리했지만 그렇다고 다른 코드가 불필요한 것은 아니다.

일단은 initState로 뭉뚱그려 이야기했지만 사실 그 안에 있는 것들이 더 중요하다. 

 

코드를 봐보자.

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
    setState(() {
      canShowSplash = false;
    });
    await Future.delayed(Duration(seconds: 3));
    Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) {
      return Scaffold();
    },));
  },);
}

 

일단은 이 코드를 보면 맨 처음 화면이 시작될 때 initState() 를 호출하면서 이 코드로 들어온다.

 

그런 후 addPostFramCallback 을 거치는데 이는 위젯이 첫 번째 프레임이 랜더링 된 후에 콜백을 실행하게 해 준다.

 

async는 밑에서 await를 사용할 것이기 때문에 써준다.

 

암튼 그렇게 해서 내부에선 setState로 ui를 다시 그리도록(?) 만들어주고  그 안에서 선언해 놨던 불리언 값을 false로 바꾸는 것이다. (굳이 꼭 처음에 선언할 때 true이고 setState안에서 false로 바꾸진 않아도 된다. 반대로 해도 되는데 나는 그저 밑에 애니메이션 코드에서 느낌표 붙이기 귀찮은 것이다.)

 

그렇게 한 후 await를 써줘서 비동기적으로 되게 만드는 것이다. (이거 안 쓰면 그냥 바로 화면이 넘어가 버린다.) 그런 다음

Future.delayed(Duration(seconds: 3)); 을 사용해서 3초간 기다려 주는 거다. 뭘 기다리는 거냐면 밑에 애니메이션이 동작할 시간을 기다려 주는 것이다.

 

그리고 밑에는 Navigator 문을 사용해서 이동해 줄 것인데 스플래시 화면은 다시 돌아오면 안 되니까 pushReplacement 값으로 돌아오지 못하게 해 줄 것이다.

 

그다음에는 빌드 위젯이다. 빌드 위젯은 다른 건 볼 것 없고 Animatedopacity 안에 있는 값만 좀 보면 되겠다.

AnimatedOpacity(
  duration: Duration(seconds: 2),
  opacity: canShowSplash ? 0 : 1,
  child: Image.asset('assets/IMG_3467.jpg', width: 300,),
),

 

먼저 duration 값이다. 이 값은 실행되는 시간을 지정할 수 있는 값인데 여기다가는 우리가 아까 위에서 3초 동안 기다려 주고 있으니까 안에서는 3초 이내 시간으로 동작시키면 된다. 2초를 동작시키든지 1초를 동작시키든지 자기 마음대로 하면 된다. 

 

그다음은 opacity 값이다. 이제 맨 처음 선언해 둔 불리언 값의 상태는 true 이다. 그니까 현재 이 코드에서는true일 때는 오파시티 값이 0인거이다. 근데 화면이 실행되면 이니스테이트 문이 호출되고 그 안에는 불리언 값을 false로 만들어 주는 코드가 있다. 그렇게 화면이 실행되면 오파시티 값은 false, 곧 1이 된다. 

 

그다음 밑에 child 값 안에는 컨테이너를 만들어서 넣든, 이미지를 넣든 텍스트를 넣든 마음대로 하면 된다. 

 

추가로 다른 애니메이션들도 보여주겠다.

 

 AnimatedSlide

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    body: Column(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        AnimatedSlide(
          offset: Offset(0, canShowSplash ? -2 : 0),
          duration: Duration(seconds: 2),
          curve: Curves.easeInOut,
          child: Transform.scale(
            scale: 2,
            child: Container(
              width: double.infinity,
              height: 400,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(1000)),
                color: Colors.black,
              ),
            ),
          ),
        ),
        Image.asset('assets/KIA_Logo_white.png', width: 200, color: Colors.white,),
      ],
    ),
  );
}

 

AnimatedContainer

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: AnimatedContainer(
        duration: Duration(seconds: 2),
        width: canShowSplash ? 0 : 200,
        height: canShowSplash ? 0 : 200,
        child: Image.asset('assets/IMG_3467.jpg'),
      ),
    ),
  );
}

 

이렇게 스플래시 화면을 구성하는 방법과 애니메이션을 3개를 알아보았다.

(애니메이션 값안에 내가 적지 않은 효과들도 많으니 참고 바란다.)

 

초보자도 이해하기 쉽게 설명해 놨으니 도움이 되었길 바라며 포스팅 마치겠다.

반응형

 

반응형