플러터 다크모드 핵심 Brightness 속성 파헤치기

오늘날 모바일 앱 개발에서 '테마'는 단순히 보기 좋은 디자인을 넘어 사용자 경험(UX)의 핵심 요소로 자리 잡았습니다. 특히 사용자의 눈의 피로를 덜어주고 배터리 소모를 줄여주는 '다크 모드'는 이제 선택이 아닌 필수 기능이 되었습니다. Flutter는 머티리얼 디자인(Material Design) 시스템을 기반으로 매우 유연하고 강력한 테마 시스템을 제공하며, 그 중심에는 바로 Brightness 속성이 있습니다. 많은 개발자들이 다크 모드를 구현할 때 Brightness를 처음 접하게 되지만, 이 속성이 단순히 화면을 어둡게 만드는 스위치 이상의 역할을 한다는 사실을 아는 것은 중요합니다. `Brightness`는 Flutter 테마 시스템의 근간을 이루는 개념으로, 앱의 모든 색상과 위젯 스타일에 깊숙이 관여합니다.

이 글에서는 풀스택 개발자의 관점에서 Flutter의 ThemeDataBrightness 속성을 심층적으로 분석합니다. 단순히 Brightness.lightBrightness.dark를 설정하는 방법을 넘어, 이 두 가지 값이 앱의 다른 색상 속성들에 어떤 연쇄적인 영향을 미치는지, 그리고 이를 어떻게 활용하여 체계적이고 확장 가능한 테마를 구축할 수 있는지 알아볼 것입니다. 또한, 최신 Flutter에서 권장하는 ColorScheme과의 관계를 살펴보고, 최종적으로는 시스템 설정에 따라 자동으로 라이트/다크 모드를 전환하고 사용자에게 선택권까지 제공하는 실전적인 구현 방법까지 상세하게 다룰 것입니다. 이 글을 끝까지 읽으신다면, Brightness에 대한 완벽한 이해를 바탕으로 사용자에게 사랑받는 앱을 만들 수 있는 튼튼한 기초를 다지게 될 것입니다.

Flutter 테마의 심장: ThemeData와 Brightness의 첫 만남

Flutter 앱의 시각적 정체성은 MaterialApp 위젯의 theme 속성에 전달되는 ThemeData 객체에 의해 결정됩니다. ThemeData는 앱의 기본 색상 팔레트, 글꼴, 버튼 스타일, 입력 필드 디자인 등 UI의 거의 모든 측면을 정의하는 거대한 설정 값들의 집합체입니다. 이 거대한 설정의 가장 기본이 되는 축이 바로 Brightness입니다.

Brightnessenum 타입으로, 단 두 가지 값만을 가집니다: Brightness.lightBrightness.dark. 이름에서 직관적으로 알 수 있듯이, 이는 각각 밝은 테마(라이트 모드)와 어두운 테마(다크 모드)를 의미합니다.

가장 기본적인 설정 방법은 ThemeData 생성자에 brightness 속성을 직접 명시하는 것입니다.


// main.dart
import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Brightness Demo',
      // Brightness.light 설정 (기본값)
      theme: ThemeData(
        brightness: Brightness.light,
        primarySwatch: Colors.blue, // 예시를 위한 primarySwatch 설정
      ),
      home: const MyHomePage(title: 'Light Theme Demo'),
    );
  }
}

// ... (MyHomePage 위젯 코드는 아래에서 계속)

위 코드는 가장 일반적인 라이트 모드 설정입니다. 사실 ThemeData()의 기본 brightness 값은 Brightness.light이므로 명시적으로 작성하지 않아도 동일하게 동작합니다. 이제 brightnessBrightness.dark로 변경해 보겠습니다.


// ...
    return MaterialApp(
      title: 'Flutter Brightness Demo',
      // Brightness.dark 설정
      theme: ThemeData(
        brightness: Brightness.dark,
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Dark Theme Demo'),
    );
// ...

단지 이 한 줄의 변경만으로 앱의 전반적인 모습이 극적으로 변합니다. 배경은 어두운 색으로, 텍스트는 밝은 색으로 자동 조정됩니다. 아래는 각 Brightness 설정에 따른 앱의 변화를 보여주는 예시입니다.

brightness - light example
Brightness.light 적용 예시
brightness - dark example
Brightness.dark 적용 예시

여기서 중요한 질문이 나옵니다. "나는 단지 brightness만 바꿨을 뿐인데, 어떻게 배경색, 글자색, 앱 바 색상 등이 모두 알아서 조화롭게 바뀐 것일까?" 이 질문에 대한 답이 바로 Brightness의 핵심 원리이자 Flutter 테마 시스템의 강력함입니다.

핵심 포인트: Brightness는 단순히 '밝다' 또는 '어둡다'는 상태를 나타내는 플래그가 아닙니다. 이 값은 ThemeData 내에서 명시적으로 설정되지 않은 수많은 다른 색상 속성들의 기본값을 결정하는 '기준점' 역할을 합니다.

Brightness가 테마 색상을 지배하는 원리: 파생 색상의 비밀

ThemeData 생성자를 보면 scaffoldBackgroundColor, canvasColor, cardColor, disabledColor 등 수십 개의 색상 관련 속성들이 존재합니다. 우리가 ThemeData(brightness: Brightness.dark)와 같이 최소한의 정보만 제공했을 때, Flutter 프레임워크는 이 brightness 값을 기반으로 머티리얼 디자인 가이드라인에 맞는 합리적인 기본 색상 세트를 '파생(derive)'시켜 나머지 속성들을 채워 넣습니다.

예를 들어, Brightness.light일 때 scaffoldBackgroundColor는 거의 흰색에 가까운 색(Colors.grey[50])으로, canvasColor는 흰색(Colors.white)으로, 기본 텍스트 색상은 검은색 계열로 설정됩니다. 반면 Brightness.dark일 때는 scaffoldBackgroundColor가 거의 검은색에 가까운 색(Colors.grey[850])으로, canvasColor는 그보다 약간 밝은 어두운 색(Colors.grey[900])으로, 텍스트 색상은 흰색 계열로 파생됩니다.

이러한 파생 규칙 덕분에 개발자는 모든 색상을 일일이 지정하는 수고를 덜고, brightness 하나만으로도 일관성 있는 라이트/다크 테마의 기본 골격을 만들 수 있습니다. 아래 표는 brightness 값에 따라 일부 주요 색상 속성들의 기본값이 어떻게 달라지는지를 보여줍니다. (실제 값은 Flutter 버전에 따라 미세하게 다를 수 있습니다.)

ThemeData 속성 Brightness.light 기본값 Brightness.dark 기본값 설명
scaffoldBackgroundColor Colors.grey[50] (#FAFAFA) Colors.grey[850] (#303030) 앱 화면의 기본 배경색
canvasColor Colors.white (#FFFFFF) Colors.grey[900] (#212121) Card, Drawer 등의 배경색
cardColor Colors.white (#FFFFFF) Colors.grey[800] (#424242) Card 위젯의 기본 배경색
textTheme.bodyLarge.color Colors.black87 Colors.white87 본문 텍스트의 기본 색상
dividerColor Colors.black38 Colors.white38 구분선의 색상
disabledColor Colors.black38 Colors.white38 비활성화된 위젯의 색상
hintColor Colors.black54 Colors.white54 TextField의 힌트 텍스트 색상

물론, 이 파생된 값들은 언제든지 개발자가 직접 덮어쓸 수 있습니다. 예를 들어, 다크 모드에서도 특정 배경색을 사용하고 싶다면 다음과 같이 코드를 작성하면 됩니다.


ThemeData(
  brightness: Brightness.dark,
  scaffoldBackgroundColor: const Color(0xFF1A237E), // 남색 계열의 어두운 배경
  // 다른 속성들은 여전히 Brightness.dark를 기준으로 파생됨
)

이처럼 Brightness는 테마 커스터마이징의 시작점입니다. 기본 골격을 제공받고, 필요한 부분만 선택적으로 수정함으로써 효율적인 테마 관리가 가능해집니다.

경험에서 나온 조언: 개발 초기에는 Brightness만 설정하여 빠르게 라이트/다크 모드를 구현하고, 앱의 전체적인 디자인이 구체화됨에 따라 필요한 색상들을 하나씩 커스터마이징하는 점진적인 접근 방식을 추천합니다. 처음부터 모든 색상을 정의하려고 하면 작업량이 방대해지고 일관성을 해치기 쉽습니다.

Brightness를 넘어서: 현대적인 테마 설계 با ColorScheme

지금까지 Brightness와 개별 색상 속성(primaryColor, scaffoldBackgroundColor 등)을 직접 다루는 방법을 알아보았습니다. 이 방법은 여전히 유효하지만, 머티리얼 디자인 2와 3가 도입되면서 Flutter는 더욱 체계적이고 의미론적인 색상 관리 시스템인 ColorScheme을 사용할 것을 강력히 권장하고 있습니다.

ColorScheme은 앱의 핵심 색상들을 역할에 따라 정의하는 작은 색상 팔레트입니다. 예를 들어, `primary`(주요 색상), `secondary`(보조 색상), `surface`(카드, 시트 등의 표면 색상), `background`(배경색), `error`(오류 색상) 등이 있으며, 각 색상 위에 표시될 콘텐츠(텍스트, 아이콘 등)를 위한 `onPrimary`, `onSecondary`, `onSurface` 등의 'on' 색상도 함께 정의합니다. 이 방식의 가장 큰 장점은 색상의 '용도'에 집중하게 하여 디자인 시스템을 더 견고하게 만들 수 있다는 점입니다.

ColorScheme 역시 brightness 속성을 가지고 있습니다. 그리고 ThemeData.from(colorScheme: ...) 팩토리 생성자를 사용하면, 주어진 ColorScheme을 기반으로 훨씬 더 정교하게 파생된 ThemeData를 만들 수 있습니다. 이 때 ThemeDatabrightness는 자동으로 ColorSchemebrightness를 따라갑니다.

현대적인 방식으로 라이트/다크 테마를 정의하는 방법은 다음과 같습니다.


// 1. Light ColorScheme 정의
const lightColorScheme = ColorScheme(
  brightness: Brightness.light,
  primary: Color(0xFF6200EE),
  onPrimary: Colors.white,
  secondary: Color(0xFF03DAC6),
  onSecondary: Colors.black,
  error: Color(0xFFB00020),
  onError: Colors.white,
  background: Color(0xFFFFFFFF),
  onBackground: Colors.black,
  surface: Color(0xFFFFFFFF),
  onSurface: Colors.black,
);

// 2. Dark ColorScheme 정의
const darkColorScheme = ColorScheme(
  brightness: Brightness.dark,
  primary: Color(0xFFBB86FC),
  onPrimary: Colors.black,
  secondary: Color(0xFF03DAC6),
  onSecondary: Colors.black,
  error: Color(0xFFCF6679),
  onError: Colors.black,
  background: Color(0xFF121212),
  onBackground: Colors.white,
  surface: Color(0xFF121212),
  onSurface: Colors.white,
);

// 3. MaterialApp에 적용
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.from(colorScheme: lightColorScheme),
      darkTheme: ThemeData.from(colorScheme: darkColorScheme),
      // themeMode는 아래에서 자세히 다룹니다.
      themeMode: ThemeMode.system, 
      home: const MyHomePage(title: 'ColorScheme Demo'),
    );
  }
}

이 접근 방식은 ThemeData의 개별 속성을 하나하나 설정하는 것보다 훨씬 간결하고 유지보수가 용이합니다. 브랜드의 핵심 색상 몇 가지만 ColorScheme으로 정의하면, Flutter가 나머지 수많은 위젯들의 스타일을 일관되게 처리해주기 때문입니다. Brightness는 이 ColorScheme의 가장 중요한 속성 중 하나로서, 라이트/다크 팔레트를 구분하는 역할을 충실히 수행합니다.

실전: 시스템 설정에 따른 다크/라이트 모드 자동 전환

이제 이론을 바탕으로 가장 실용적인 기능인 '시스템 설정 연동 자동 테마 전환'을 구현해 보겠습니다. 대부분의 사용자는 스마트폰의 OS 설정(iOS의 '화면 스타일', Android의 '어두운 테마')에서 선호하는 모드를 이미 설정해두었습니다. 우리 앱이 이 설정을 존중하여 자동으로 테마를 바꿔준다면 훨씬 더 좋은 사용자 경험을 제공할 수 있습니다.

Flutter는 이 기능을 놀라울 정도로 간단하게 구현할 수 있도록 지원합니다. 바로 MaterialApptheme, darkTheme, themeMode 세 가지 속성을 함께 사용하는 것입니다.

  1. theme: 앱의 기본 테마, 즉 라이트 모드일 때 사용할 ThemeData를 지정합니다.
  2. darkTheme: 다크 모드일 때 사용할 ThemeData를 지정합니다.
  3. themeMode: 어떤 테마를 적용할지 결정하는 속성입니다. ThemeMode enum 값을 가집니다.
    • ThemeMode.light: 항상 theme에 지정된 라이트 테마만 사용합니다.
    • ThemeMode.dark: 항상 darkTheme에 지정된 다크 테마만 사용합니다.
    • ThemeMode.system: 시스템(OS) 설정에 따라 themedarkTheme 사이를 자동으로 전환합니다. 우리가 원하는 것이 바로 이것입니다!

앞서 `ColorScheme` 예제에서 이미 구현했지만, 전체 코드를 다시 한번 명확하게 살펴보겠습니다.


import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    // 라이트 모드 테마 데이터 정의
    final lightTheme = ThemeData(
      brightness: Brightness.light,
      primarySwatch: Colors.indigo,
      // 추가적인 라이트 모드 커스텀...
    );

    // 다크 모드 테마 데이터 정의
    final darkTheme = ThemeData(
      brightness: Brightness.dark,
      primarySwatch: Colors.teal,
      // 추가적인 다크 모드 커스텀...
    );

    return MaterialApp(
      title: 'Automatic Theme Switching',
      theme: lightTheme, // 라이트 모드 테마 적용
      darkTheme: darkTheme, // 다크 모드 테마 적용
      themeMode: ThemeMode.system, // 시스템 설정에 따라 자동 전환
      home: const MyHomePage(title: 'System Theme'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // 현재 적용된 테마의 Brightness를 확인
    final brightness = Theme.of(context).brightness;
    final themeModeString = brightness == Brightness.light ? 'Light Mode' : 'Dark Mode';

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Currently in:',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            Text(
              themeModeString,
              style: Theme.of(context).textTheme.headlineLarge?.copyWith(
                fontWeight: FontWeight.bold,
                color: Theme.of(context).colorScheme.primary,
              ),
            ),
            const SizedBox(height: 20),
            const Text(
              '휴대폰의 설정 > 디스플레이에서\n라이트/다크 모드를 변경해보세요.',
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
실행해보세요! 위 코드를 실제 기기나 에뮬레이터에서 실행한 후, 기기의 시스템 설정을 변경하면 앱이 즉시 반응하여 테마를 전환하는 것을 확인할 수 있습니다. 별도의 상태 관리나 리스너 없이, 단지 MaterialApp의 속성 설정만으로 이 모든 것이 가능합니다.

이처럼 Brightness를 기반으로 라이트/다크 ThemeData를 각각 정의하고, themeModesystem으로 설정하는 것이 Flutter에서 다크 모드를 지원하는 가장 표준적이고 효율적인 방법입니다.

한 걸음 더: 사용자가 직접 테마를 선택하게 하기

시스템 설정 자동 연동은 훌륭한 기능이지만, 앱 내에 직접 테마를 변경할 수 있는 옵션(예: 라이트/다크/시스템 설정)을 제공하여 사용자에게 더 많은 제어권을 주는 것이 좋습니다. 이를 구현하려면 앱의 상태(현재 선택된 ThemeMode)를 관리하고, 이 상태가 변경될 때마다 MaterialApp을 다시 빌드해야 합니다. 여기서는 간단한 예시를 위해 ValueNotifierValueListenableBuilder를 사용하지만, Provider, Riverpod, BLoC 등 선호하는 어떤 상태 관리 솔루션으로도 동일한 로직을 구현할 수 있습니다.

1. 테마 모드를 관리할 ValueNotifier 생성

앱의 전역적인 상태로 관리하기 위해 main 함수 바깥이나 별도의 상태 관리 파일에 선언합니다.


// main.dart 상단
final ValueNotifier<ThemeMode> themeNotifier = ValueNotifier(ThemeMode.system);

2. MaterialAppValueListenableBuilder로 감싸기

themeNotifier의 값이 변경될 때마다 MaterialApp이 새로운 themeMode로 다시 빌드되도록 합니다.


// main.dart의 main 함수
void main() {
  runApp(
    ValueListenableBuilder<ThemeMode>(
      valueListenable: themeNotifier,
      builder: (_, ThemeMode currentMode, __) {
        return const MyApp(); // MyApp 내부에서 currentMode를 사용하도록 수정 필요
      },
    ),
  );
}

// MyApp 위젯 수정
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<ThemeMode>(
      valueListenable: themeNotifier,
      builder: (_, ThemeMode currentMode, __) {
        return MaterialApp(
          // ... theme, darkTheme 설정은 동일 ...
          themeMode: currentMode, // notifier의 현재 값으로 themeMode 설정
          home: const MyHomePage(title: 'User Selectable Theme'),
        );
      },
    );
  }
}

수정: 초기 로직은 MyApp 자체를 다시 빌드하는 것이었으나, MaterialApp의 themeMode를 직접 업데이트하는 것이 더 효율적입니다. MyApp 내부에서 ValueListenableBuilder를 사용하는 것으로 코드를 개선합니다.

3. 사용자에게 선택 옵션을 제공하는 UI 구현

설정 페이지나 팝업 메뉴 등에서 사용자가 테마를 선택할 수 있는 UI를 만듭니다. 여기서는 AppBar의 액션 버튼으로 간단히 구현해보겠습니다.


// MyHomePage 위젯의 Scaffold 내부
// ...
appBar: AppBar(
  title: Text(widget.title),
  actions: [
    PopupMenuButton<ThemeMode>(
      onSelected: (ThemeMode item) {
        // Notifier의 값을 변경하여 테마를 업데이트
        themeNotifier.value = item;
      },
      itemBuilder: (BuildContext context) => <PopupMenuEntry<ThemeMode>>[
        const PopupMenuItem<ThemeMode>(
          value: ThemeMode.light,
          child: Text('라이트 모드'),
        ),
        const PopupMenuItem<ThemeMode>(
          value: ThemeMode.dark,
          child: Text('다크 모드'),
        ),
        const PopupMenuItem<ThemeMode>(
          value: ThemeMode.system,
          child: Text('시스템 설정'),
        ),
      ],
    ),
  ],
),
// ...

이제 사용자가 앱 바의 메뉴를 통해 테마를 선택하면 themeNotifier.value가 변경되고, ValueListenableBuilder가 이를 감지하여 MaterialApp을 새로운 themeMode 값으로 재구성합니다. 이로써 완벽한 사용자 정의 테마 선택 기능이 완성되었습니다. 이 모든 과정의 중심에는 결국 Brightness를 기반으로 정의된 두 개의 ThemeData가 있다는 것을 기억하는 것이 중요합니다.

Brightness 사용 시 주의할 점과 고급 팁

Brightness와 테마 시스템을 다룰 때, 더 완성도 높은 앱을 만들기 위해 몇 가지 고려해야 할 사항들이 있습니다.

⚠️ 색상 하드코딩을 피하세요!

가장 흔한 실수 중 하나는 위젯 스타일에 색상을 직접 하드코딩하는 것입니다. 예를 들어, 라이트 모드에서 보기 좋다고 다음과 같이 코드를 작성했다고 가정해 봅시다.

Container(color: Colors.white, child: Text('Hello', style: TextStyle(color: Colors.black)))

이 코드는 다크 모드로 전환되었을 때 재앙이 됩니다. 어두운 배경 위에 여전히 흰색 컨테이너와 검은색 텍스트가 표시되어 매우 부자연스럽고 가독성이 떨어집니다. 항상 테마에 정의된 색상을 사용하는 습관을 들여야 합니다.

올바른 방법:
Container( color: Theme.of(context).colorScheme.surface, child: Text('Hello', style: TextStyle(color: Theme.of(context).colorScheme.onSurface)) )

Theme.of(context)를 통해 현재 적용된 테마의 색상(특히 ColorScheme의 의미론적 색상)을 가져와 사용하면, 앱이 라이트/다크 모드를 전환할 때마다 해당 위젯의 색상도 자동으로 적절하게 변경됩니다.

  • 접근성(Accessibility): 라이트/다크 모드 모두에서 텍스트와 배경 간의 명도 대비가 충분히 확보되어야 합니다. WCAG(웹 콘텐츠 접근성 지침) 기준을 참고하여 색상을 선택하는 것이 좋습니다. ColorScheme의 `on` 색상들을 사용하면 대부분의 경우 좋은 대비를 보장받을 수 있습니다.
  • 이미지 및 에셋: 다크 모드에서는 너무 밝은 이미지나 아이콘이 눈에 띄어 사용자에게 불편함을 줄 수 있습니다. 가능하다면 다크 모드용 에셋을 별도로 준비하거나, 이미지에 어두운 필터를 적용하는 등의 처리를 고려해볼 수 있습니다.
  • 위젯별 테마 오버라이드: 앱의 특정 부분만 다른 테마를 적용하고 싶을 때가 있습니다. 예를 들어, 앱 전체는 라이트 모드이지만 특정 카드 위젯만 다크 모드로 보여주고 싶을 수 있습니다. 이럴 때는 `Theme` 위젯으로 해당 위젯을 감싸고, `data` 속성에 새로운 `ThemeData`를 제공하면 됩니다.
    
    Theme(
      data: ThemeData(brightness: Brightness.dark),
      child: Card(
        child: Text('이 카드는 항상 다크 모드입니다.'),
      ),
    )
    
  • 시스템 Brightness vs 앱 Brightness: MediaQuery.of(context).platformBrightness는 OS의 현재 설정을 직접 알려주는 값입니다. 반면 Theme.of(context).brightness는 앱에 현재 '적용된' 테마의 `Brightness` 값입니다. themeModeThemeMode.light로 고정되어 있다면, 시스템이 다크 모드여도(platformBrightnessdark) 앱의 `brightness`는 항상 light가 됩니다. 이 두 속성의 차이를 이해하면 더 복잡한 로직을 구현할 때 혼란을 피할 수 있습니다.

마치며: Brightness는 단순한 시작일 뿐

Flutter의 Brightness는 단순한 라이트/다크 모드 스위치를 넘어, 앱의 전체적인 색상 시스템을 지배하는 근본적인 속성입니다. Brightness가 어떻게 다른 색상들을 파생시키는지, 그리고 현대적인 ColorScheme과 어떻게 조화롭게 작동하는지를 이해함으로써 우리는 비로소 체계적이고 확장 가능한 테마 시스템을 설계할 수 있습니다.

오늘 우리는 Brightness의 기본 개념부터 시작해, MaterialApptheme, darkTheme, themeMode를 활용한 손쉬운 자동 테마 전환, 그리고 상태 관리를 통한 사용자 직접 선택 기능 구현까지의 여정을 함께했습니다. 이제 여러분은 어떤 Flutter 프로젝트를 맡더라도 자신감 있게 라이트/다크 모드를 구현하고, 사용자의 선호에 부응하는 세련된 앱을 만들 수 있는 강력한 무기를 갖게 되었습니다.

테마는 사용자가 앱과 처음 만나는 순간부터 계속해서 상호작용하는 중요한 요소입니다. 이 글에서 다룬 Brightness에 대한 깊은 이해를 바탕으로, 사용자의 눈을 편안하게 하고 앱의 브랜드 정체성을 빛내주는 멋진 테마를 만들어 보시길 바랍니다.

더 자세한 정보는 Flutter 공식 문서의 테마 쿡북을 참고하시면 좋습니다.

Post a Comment