[TIL-004] 내가 Dart, Flutter 중에 무엇을 사용하고 있는 것일까?

특정 언어를 기반으로 만들어진 프레임워크를 공부하다 보면 지금 공부하고 있는 함수나 객체가 그 언어의 내장 함수나 내장 객체인지 아니면 프레임워크의 것인지 구별을 하기가 쉽지 않다.

 

Dart언어를 기반으로 하는 Flutter 프레임워크도 마찬가지이다.

위젯이라고 표현하는 여러 함수와 클래스가 Dart의 내장 클래스인지 아닌지 헷갈린다.

 

그래서 오늘은 Flutter의 예시 코드를 보면서 Dart의 내장 클래스인지 Flutter의 위젯인지 구별하는 방법을 찾아볼까 한다.

 


Dart와 Flutter 구분하기

예시 코드

import 'package:httphttp.dart' as http;

Future<String> fetchData() async {
  final url = Uri.parse('https://jsonplaceholder.typicode.com/posts');
  final response = await http.get(url);
  print(response.body);
  return '데이터 로드 완료';
}

Dart의 언어 요소

Dart의 모든 것은 클래스로 구성되어 있다.

  1. `Future<String>`
    • Dart의 `Future` 클래스이다.
    • `Future`는 비동기 작업의 결과를 나타내는 객체로, 나중에 값이 반환될 것을 의미한다.
    • 함수의 반환 타입의 역할을 한다.
  2. `fetchData() async`
    • Dart의 비동기 함수(async function)이다.
    • `async` 키워드가 붙어 있어, 함수 내부에서 `await`을 사용할 수 있다.
    • 이 함수는 `Future<String>`을 반환하며, 비동기 작업을 수행한 후 문자열 데이터를 반환한다.
  3. ` Uri.parse('https://jsonplaceholder.typicode.com/posts')`
    • Dart의 `Uri` 클래스이다.
    • `parse()` 는 `Uri`의 정적 메서드이다. 문자열을 새로운 `Uri` 객체로 반환한다.
  4. `await http.get(url)`
    • Flutter에서 API 통신을 좀 더 쉽게 하기 위한 http 라이브러리의 객체이다.
  5. `print(response.body)`
    • Dart의 함수이며 콘솔에 값을 출력한다.

Flutter의 위젯

Flutter의 모든 것은 위젯과 클래스로 구성되어 있다.

`예시 코드`에서는 위젯이나 클래스가 사용되지 않았다.

 

실전 코드

아래의 앱을 만들어보자.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(debugShowCheckedModeBanner: false, home: TikTokScreen());
  }
}

class TikTokScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          // Background Video or Image
          Positioned.fill(
            child: Image.network(
              'https://images.unsplash.com/photo-1590698933947-a202b069a861?q=80&w=1470&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
              fit: BoxFit.cover,
            ),
          ),

          // Overlay Icons and Buttons
          Positioned(
            right: 16,
            bottom: 100,
            child: Column(
              children: [
                Icon(Icons.favorite, color: Colors.white, size: 40),
                Text('1.4만', style: TextStyle(color: Colors.white)),
                SizedBox(height: 20),
                Icon(Icons.comment, color: Colors.white, size: 40),
                Text('1,269', style: TextStyle(color: Colors.white)),
                SizedBox(height: 20),
                Icon(Icons.share, color: Colors.white, size: 40),
                Text('960', style: TextStyle(color: Colors.white)),
              ],
            ),
          ),

          // Bottom Navigation Bar
          Positioned(
            bottom: 0,
            left: 0,
            right: 0,
            child: Container(
              color: Colors.black.withOpacity(0.7),
              padding: EdgeInsets.symmetric(vertical: 10, horizontal: 16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    '스마일',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 18,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  Text(
                    '모두 웃어요:), 신발은 덤',
                    style: TextStyle(color: Colors.white, fontSize: 14),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Dart 언어 요소

코드 설명
`import 'package:flutter/material.dart';` Dart의 import 문법을 사용하여 Flutter 패키지를 불러옴
`void main() { runApp(MyApp()); }` Dart의 `main` 함수 (프로그램 실행 시작점)
`class MyApp extends StatelessWidget {}` Dart 클래스 선언. 대신 Flutter의 위젯을 상속하는 클래스
`@override` Dart의 메서드 오버라이딩 문법

 

Flutter 위젯

코드 설명
`runApp()` Flutter가 앱을 실행하고, UI를 화면에 표시하기 위한 함수
`MaterialApp()` Flutter 앱의 루트 위젯(root widget) 역할을 하며, 앱의 기본적인 설정을 담당
`build()` UI를 생성하고 반환하는 메서드. `build` 안에서 위젯을 조합해 화면을 구성
`Scaffold()` 기본적인 화면 레이아웃을 담당하는 위젯
`Stack()` 여러 위젯을 겹쳐서 배치할 수 있는 위젯
`Positioned()` Stack 내부에서 특정 위치에 위젯을 배치하는 역할
`Image` 이미지를 화면에 표시하는 위젯
`Column()` 위젯을 수직으로 정렬하는 위젯
`Text()` 텍스트를 화면에 출력하는 위젯
`Icon()` 아이콘을 표시하는 위젯
`SizedBox()` 특정한 너비(width) 또는 높이(height) 를 가지는 빈 박스를 만드는 데 사용하는 위젯. 이 위젯을 활용하면 위젯 사이의 간격을 조절 가능
`EdgeInsets` 위젯의 패딩(Padding)이나 마진(Margin)을 설정하는 클래스
`Colors` 색상을 정의하는 클래스
`TextStyle()` 위젯의 글꼴, 크기, 색상 등을 지정하는 스타일 클래스
`Container()` 배경색 및 패딩을 추가할 수 있는 박스형 위젯

 

결과

위젯은 UI를 그리기 위한 함수나 클래스를 나타내는 것이고, Dart의 쓰임새는 위젯을 호출할 때 필요한 로직을 만들기 위해 사용한다.

 

💡 위젯을 구별하는 방법

✅ `build` 메서드 안에서 사용되는 대부분의 요소는 Flutter의 위젯이다.
✅ 위젯을 반환하는 함수나 클래스는 위젯이다.
✅ 대부분의 Flutter 위젯은 대문자로 시작한다.

 

앞으로는 모르는게 있으면 어떤 공식문서를 참조해야 할지 바로 알 수 있을 것 같다.