본문 바로가기
Flutter

Flutter 사용 기본사항

by ERLite 2026. 5. 15.
 
Flutter는 Dart 언어를 기반으로 하며, 기본 문법은 변수 선언, 함수, 제어문, 컬렉션, 객체지향 프로그래밍, 그리고 위젯 구조로 구성됩니다. Dart 문법을 이해하는 것이 Flutter 앱 개발의 출발점입니다.

📝 Dart 기본 문법

  • 프로그램 구조 모든 Dart 프로그램은 main() 함수에서 시작합니다.
  • dart
    void main() {
      print('Hello, Flutter!');
    }
    
  • 변수 선언
    • 타입 명시: String name = '홍길동';
    • 타입 추론: var age = 30;
    • 동적 타입: dynamic value = '문자열';
  • 상수
    • final: 런타임에 값 결정
    • const: 컴파일 타임에 값 결정
  • 데이터 타입
    • 숫자: int, double, num
    • 문자열: String
    • 불리언: bool
    • 리스트: List<int> numbers = [1,2,3];
    • 맵: Map<String, dynamic> person = {'name':'홍길동'};
    • 집합: Set<String> names = {'홍길동','김철수'};

🔄 제어문과 반복문

  • 조건문
  • dart
    if (age > 18) {
      print('성인');
    } else {
      print('미성년자');
    }
    
  • 반복문
  • dart
    for (var i = 0; i < 5; i++) {
      print(i);
    }
    

⚙️ 함수와 객체지향

  • 함수
  • dart
    int add(int a, int b) {
      return a + b;
    }
    
  • 클래스
  • dart
    class Person {
      String name;
      int age;
      Person(this.name, this.age);
    }
    

🎨 Flutter 위젯 기본 문법

  • StatelessWidget 상태가 변하지 않는 위젯
  • dart
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(title: Text('Hello Flutter')),
            body: Center(child: Text('안녕하세요!')),
          ),
        );
      }
    }
    
  • StatefulWidget 상태가 변하는 위젯 (예: 버튼 클릭 시 값 변경)

🚨 주의할 점

  • Null Safety: Dart는 null 안전성을 지원합니다. 변수 선언 시 String? name;처럼 nullable 타입을 명시해야 합니다.
  • 비동기 프로그래밍: async/await를 활용해 네트워크 요청이나 파일 입출력을 처리합니다.

 

⚙️ Flutter 위쳇 생명주기

Flutter 위젯 생명주기는 위젯이 생성되고, 화면에 표시되며, 상태가 변경되고, 결국 소멸되는 전 과정을 의미합니다. 특히 StatefulWidgetinitState → build → dispose 흐름을 이해하는 것이 핵심입니다.

🟦 StatelessWidget 생명주기

  • build
    • 유일한 생명주기 메서드
    • 위젯이 생성될 때 한 번 호출
    • 상태가 없으므로 이후 변경 불가
    dart
    class HelloText extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Text('Hello Flutter!');
      }
    }
    

🟩 StatefulWidget 생명주기 단계

단계설명활용 예시
createState State 객체 생성 (한 번만 호출) 상태 관리 객체 준비
initState 초기화 로직 실행 API 호출, 컨트롤러 초기화
didChangeDependencies 종속성 변경 시 호출 MediaQuery, Provider 사용
build UI 렌더링, 상태 변경 시 재호출 화면 업데이트
setState 상태 변경 후 UI 갱신 버튼 클릭 시 카운트 증가
didUpdateWidget 부모 위젯 변경 시 호출 새로운 데이터 반영
deactivate 위젯 트리에서 제거 직전 호출 거의 사용되지 않음
dispose 리소스 해제 컨트롤러, Stream 정리
 
 

📌 예시 코드

dart
class CounterWidget extends StatefulWidget {
  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _count = 0;

  @override
  void initState() {
    super.initState();
    print('initState 호출!');
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => setState(() => _count++),
      child: Text('$_count'),
    );
  }

  @override
  void dispose() {
    print('dispose 호출!');
    super.dispose();
  }
}

🔔 앱 생명주기와 연계

  • resumed: 앱이 포그라운드로 돌아와 사용자 입력 가능
  • inactive: 포그라운드지만 입력 불가 (전화 수신 등)
  • paused: 백그라운드 실행 중
  • detached: 앱 종료 직전 상태

🚨 주의할 점

  • Hot Reload 시 initState는 다시 실행되지 않음 → 앱 재시작 필요
  • setState는 위젯이 mounted 상태일 때만 호출해야 오류 방지
  • dispose에서 리소스를 반드시 해제하지 않으면 메모리 누수 발생

 

🔔 Dart 비동기 프로래밍

Dart 비동기 프로그래밍은 Future, async, await를 활용해 네트워크 요청, 파일 입출력처럼 시간이 오래 걸리는 작업을 효율적으로 처리하는 방식입니다. 프로그램이 멈추지 않고 다른 작업을 동시에 수행할 수 있도록 해줍니다.

🔑 핵심 개념

  • Future 미래에 완료될 작업의 결과를 나타내는 객체.
  • dart
    Future<String> fetchData() {
      return Future.delayed(Duration(seconds: 2), () => "데이터 완료");
    }
    
  • async 함수가 비동기적으로 동작함을 선언. await를 사용하려면 반드시 필요.
  • await Future가 완료될 때까지 기다린 후 다음 코드 실행.
  • dart
    void main() async {
      print("데이터 요청 중...");
      String result = await fetchData();
      print(result);
    }
    

⚙️ 동작 방식

  • 동기식 코드: 순차적으로 실행 → 오래 걸리는 작업에서 프로그램이 멈춤
  • 비동기식 코드: 오래 걸리는 작업을 기다리지 않고 다른 작업을 계속 실행
  • 장점:
    • UI 응답성 유지
    • CPU 자원 효율적 사용
    • 여러 작업을 동시에 처리 가능

🛠️ 오류 처리

  • then/catchError 방식
  • dart
    fetchData().then((value) {
      print(value);
    }).catchError((error) {
      print("에러 발생: $error");
    });
    
  • try/catch 방식 (async/await)
  • dart
    try {
      String result = await fetchData();
      print(result);
    } catch (e) {
      print("에러 발생: $e");
    }
    

🔄 여러 Future 처리

  • Future.wait 여러 비동기 작업을 동시에 실행하고 모두 완료될 때까지 기다림.
  • dart
    var results = await Future.wait([fetchData(), fetchData()]);
    print(results);
    

📌 Stream (연속 데이터 처리)

  • Stream 여러 개의 비동기 이벤트를 순차적으로 전달받을 때 사용 (예: 채팅 메시지, 센서 데이터).
  • dart
    Stream<int> countStream() async* {
      for (int i = 1; i <= 5; i++) {
        await Future.delayed(Duration(seconds: 1));
        yield i;
      }
    }
    

🚨 주의할 점

  • await는 반드시 async 함수 안에서만 사용 가능
  • setState 같은 UI 갱신은 Future 완료 후 안전하게 호출해야 함
  • 비동기 작업에서 리소스 해제를 잊으면 메모리 누수 발생

'Flutter' 카테고리의 다른 글

Flutter 테트리스 소스 분석  (0) 2026.05.27
Flutter 개발환경 설치와 첫 실행  (0) 2026.05.08