[flutter] 플러터 앱의 다크 모드 (Dark Mode) 지원하기

플러터는 Google에서 개발한 크로스 플랫폼 모바일 앱 개발 프레임워크로, iOS와 Android 모두에서 동작하는 앱을 만들 수 있습니다. 최근에는 다크 모드 (Dark Mode)라고 불리는 앱의 어두운 테마 모드가 인기를 얻고 있습니다. 이번 글에서는 플러터 앱에서 다크 모드를 지원하는 방법에 대해 알아보겠습니다.

1. MaterialApp의 theme 속성 설정하기

플러터 앱에서 다크 모드를 지원하기 위해서는 MaterialApp의 theme 속성을 설정해야 합니다. MaterialApp 위젯의 theme 속성은 앱의 전반적인 테마를 정의하는 데 사용됩니다.

return MaterialApp(
  theme: ThemeData(
    brightness: Brightness.light, // 기본 테마 (라이트 모드)
    // ...
  ),
  darkTheme: ThemeData(
    brightness: Brightness.dark, // 다크 모드에서 사용될 테마
    // ...
  ),
  // ...
);

위 코드에서는 ThemeData 클래스의 brightness 속성을 사용하여 테마를 설정합니다. Brightness.light는 기본 테마 (라이트 모드)를 의미하고, Brightness.dark는 다크 모드에서 사용될 테마를 의미합니다.

2. MediaQuery를 통한 테마 설정 확인하기

플러터에서는 MediaQuery를 사용하여 현재 앱의 테마를 확인할 수 있습니다. 아래 예제 코드를 참고하여 현재 테마가 어떤 모드인지 확인할 수 있습니다.

final Brightness brightness = MediaQuery.of(context).platformBrightness;
final bool isDarkMode = brightness == Brightness.dark;

위 코드에서는 MediaQuery.of(context).platformBrightness를 사용하여 현재 테마를 확인합니다. Brightness.dark인 경우 다크 모드이고, Brightness.light인 경우 라이트 모드입니다. 이를 활용하여 앱 내에서 다크 모드에 따른 커스텀 로직을 적용할 수 있습니다.

3. 테마 변경 이벤트 처리하기

플러터 앱에서는 테마 변경 이벤트를 수신하고 이를 처리할 수 있습니다. 예를 들어, 사용자가 앱 설정에서 테마를 변경할 때마다 앱이 새로고침되어 다크 모드가 즉시 적용되도록 할 수 있습니다.

이를 위해 앱 전체를 감싸는 Root 위젯을 만들고, 이 위젯에서 테마 변경을 감지하여 앱을 새로고침하는 로직을 구현할 수 있습니다.

class RootWidget extends StatefulWidget {
  @override
  _RootWidgetState createState() => _RootWidgetState();
}

class _RootWidgetState extends State<RootWidget> {
  Brightness _brightness;

  @override
  void initState() {
    super.initState();
    _brightness = MediaQuery.of(context).platformBrightness;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        brightness: _brightness,
        // ...
      ),
      darkTheme: ThemeData(
        brightness: _brightness,
        // ...
      ),
      // ...
    );
  }
  
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _handlePlatformBrightness();
  }

  void _handlePlatformBrightness() {
    final Brightness brightness = MediaQuery.of(context).platformBrightness;
    if (_brightness != brightness) {
      setState(() {
        _brightness = brightness;
      });
    }
  }
}

위 코드에서는 RootWidget에서 initState에서 현재 테마를 가져와서 _brightness 변수에 저장합니다. 그리고 didChangeDependencies에서 현재 테마가 변경되었는지 확인하고, 변경이 있을 경우 setState를 호출하여 앱을 새로고침합니다.

이렇게 구현하면, 앱 전체에서 다크 모드에 따른 적절한 UI를 사용할 수 있습니다.

마무리

이번 글에서는 플러터 앱에서 다크 모드를 지원하는 방법에 대해 알아보았습니다. MaterialApp의 theme 속성을 이용하여 다크 모드에 사용할 테마를 설정하고, MediaQuery를 이용하여 현재 테마를 확인할 수 있습니다. 또한, 테마 변경 이벤트를 처리하는 로직을 구현하여 앱 전체에 다크 모드를 적용할 수 있습니다.

더 자세한 내용은 플러터 공식 문서를 참고하시기 바랍니다.