프로그래밍/플러터

스플래시 스크린 앱 작성

스루나루 2024. 2. 21. 18:41
728x90
728x90

 

 

Stateless Widget & Stateful Widget 

 

 

 

 - 플러터는 선언적으로 UI를 구성한다. : 위젯 내의 build 함수 내에서 상태를  반영하여 UI를 빌드 

 - f ( build ) : 앱의 상태 state를 반영하기 위해 사용자 인터페이스를 빌드 

 - state : ui를 새로 그리기 위해 필요한 데이터 

 

State

State 즉 상태라는 것은 실행 중인 앱의 메모리에 존재하는 모든 것 혹은 UI 빌드하기 위한 데이터
해당 State의 변화를 감지하여 새로 화면을 다시 그릴지 아니면 State상태 변화에 관계 없는 위젯을 만들지 플러터 프로젝트 설계를 할 때 생각해봐야할 문제이다 .

1) Statefull
 - 아무래도 사용자와 상호작용할 필요가 있음 
 - 사용자 입력, 데이터 입출력, 블루투스 연결 등 동적인 화면 구성에서 사용한다.

2) Stateless
 - 아무런 상태를 가지지 않고 한 번만 그림
 - 주로 정적인 화면 , 화면 로고 , 메뉴판 등의 화면 구성에서 사용한다. 

 

 

 1) Stateless Widget

 - 위젯 내부에서 값이 변경되어도 다시 랜더링 할 수 없는 위젯 

 - setState 호출되어도 build함수가 실행되지 않음 

 - state를 가지지 않고 한 번 생성되면 그걸로 끝 

 

 

 2) Statefull Widget

 - 위젯 내부에서 값이 변경되었을 때 마다 위젯 자체에서 다시 랜더링 실행할 수 있는 위젯 

 - setState 호출 시 build함수가 실행된다. 

 

 

SplashScreen 

 

- 스플래시 화면은 보통 어플이 기동할 때 나오는 화면으로 로딩중 등을 띄워서 본 앱이 준비되기 전까지 보여주는 화면 

 

void main() {
  //화면 전체에 SplashScreen위젯을 그릴 거니까 runApp의 매개변수로 넣어준다
  runApp(const MaterialApp(
    home: Scaffold(
      body: SplashScreen(),
    ),
  ));
}

 

 - 먼저 main에다가 runApp 매개변수로 MaterialApp을 넣어준다. 이로서 프로젝트 실행시 머티리얼 디자인 앱을 사용할 수 있는 기본 틀이 완성

 - Scaffold를 사용해서 화면에 ui를 배치 시킬 수 있도록 정리 

 - 기본적으로 프로젝트 실행할 때는 아래의 구조를 이루고 있다. 

 1) main()

 2) runApp()

 3) MaterialApp()

 4) Scaffold() 

 

 

 

 

사용된 위젯 관련 설명 

 

Container(
      decoration: const BoxDecoration(
        //color: Colors.orange,
        color: Color(0xFFF99231),
      ),

 

 1) Container 

 - 색상을 디자인 할 수 있어서 배경용으로 사용 

 - decoration 속성을 사용하고 BoxDecoration이라는 클래스의 color를 통해서 컨테이너 색상 변경이 가능 

 

 2) Color 클래스 

 - 이미 지정된 색상의 경우 Colors.색상이름 으로 사용 

 - 헥사 코드의 경우 아래 그림과 같지만 투명도 위치만 젤 앞에 위치해 있다. 

 

Image.asset(
                'assets/rupy.png',
                width: 300,
                height: 300,
              ),

 

3) Image.asset 생성자 

 - 앱에 저장된 asset 파일로 이미지를 그린다. 

 - pubspec.yaml에서 asset관련 설정을 활성화 해주고 프로젝트에 폴더를 만들어 이미지를 넣어준다. 

 - Image.asset 속성의 width , height 속성을 활용해서 크기 조절 가능 

 

 

 

 

 

주의점 

 

Row와 Colum

Row :  가로로 최대한의 크기를 차지 , 세로로 최소한의 크기를 차지 
Column : 세로로 최대한의 크기를 차지 , 가로는 최소한의 크기를 차지 

 

 

 1) Column위젯만 있고 이미지에 크기를 지정하지 않았을 때 

 

 

 

@override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        //color: Colors.orange,
        color: Color(0xFFF99231),
      ),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.asset(
            'assets/rupy.png',
            // width: 300,
            // height: 300,
          ),
          const CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation(
              Colors.white
            ),
          ),
        ],
      ),
    );
  }

- 보통 Image위젯은 원본 크기를 유지하려고 한다. 

- 해당 이미지의 경우 이미지의 크기가 지정되어 있지 않기 때문에 원본 이미지가 출력된 상태 

Container에 대해서 

1) Container에 크기를 지정하지 않을 때 
 - 하위 위젯의 크기를 제한하지 않음 
 - 하위 위젯의 원래 크기 그대로 나옴 

2) Container의 크기를 지정할 때 
- 크기를 명시적으로 지정한 경우 하위 위젯은 Container의 크기에 따라 제한이 걸림 
- Container의 크기가 200*200일 때 하위 Image가 300*300이면 크기 제한 때문에 200*200으로 축소됨 

참고로 Container는 크기 지정하지 않는 경우 가능한 가로, 세로 전부 꽉 차도록 랜더링 된다 

 

 

 2) 이미지 위젯에 크기를 명시적으로 정해줄 때 

 - 보통 이미지 위젯은 원본 크기를 유지하려고 한다. 명시적으로 지정한 경우 설정된 값에 따라 크기가 조절됨 

 - Image위젯을 감싸고 있는 Column의 경우 세로로 최대한 크게 차지하려고 하지만 가로는 최소한 차지하려고 한다. 이 때 하위 위젯인 Image가 200픽셀만 차지해버리니까 최소한으로 차지하려는 성질 때문에 Column이 차지하는 크기가 줄어들었다 

 child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.asset(
            'assets/rupy.png',
            width: 300,
            height: 300,
          ),
          const CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation(
              Colors.white,
            ),
          ),
        ],
      ),

 

3) Row위젯을 사용하자 

 - 가로를 최대한 크게 차지하려는 Row위젯으로 감싸면 Column도 Row에 맞춰서 가로 비율이 꽉 채워짐 

 

완성본

 

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: const BoxDecoration(
        //color: Colors.orange,
        color: Color(0xFFF99231),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Image.asset(
                'assets/rupy.png',
                width: 300,
                height: 300,
              ),
              const CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation(
                  Colors.white
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

 

 

 

 

참고

“이 글은 골든래빗 《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.”

 

https://docs.flutter.dev/data-and-backend/state-mgmt

 

State management

Content covering state management in Flutter apps.

docs.flutter.dev

 

728x90
728x90