Flutter로 기차 예매 서비스 만들기 회고(feat. 다크모드)
깃허브 ReadMe
https://github.com/hyewonShin/flutter-train-app
이번 과제에서 MatreialApp의 them과 darkThem을 사용하여 다크모드를 구현해보았는데, 처음에 금방하겠다는 생각과는 달리 생각보다 해매고 시간을 많이 투자했다. 그래도 어찌저찌 구현은 했지만 원래 제공해주는 방식을 효율적으로 사용하지 못했다는 것을 나중에 아차차 하고 알게되었다(아무리 그래도 비둘기가 날개라는 걸 가지고 있는데, 굳이 목으로 돌면서 날면 좀 그러니까...^^) 그런김에 잊지 않고 다음 부터는 더 효율적으로 빠르게 사용할 수 있도록 다크모드 관련한 사용 방식을 정리해두기로 했다.
main.dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
themeMode: ThemeMode.system,
theme: lightTheme,
darkTheme: darkTheme,
home: HomePage(),
);
}
}
ThemeMode.system
- 사용자의 시스템 환경 설정에 따라 달라진다.
- 맥북에서 command+ shift+a 단축키로 편하게 라이트모드와 다크모드 변환이 가능하다.
ThemeMode.light
- 강제로 라이트 모드로 고정.
ThemeMode.dark
- 강제로 다크 모드로 고정.
them.dart
final lightTheme = ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.purple),
scaffoldBackgroundColor: Colors.grey[200],
cardColor: Colors.white,
textTheme: TextTheme(
displaySmall: TextStyle(fontSize: 40, color: Colors.black),
bodyLarge: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black, fontSize: 16)));
final darkTheme = ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.purple,
brightness: Brightness.dark,
),
cardColor: const Color.fromARGB(255, 74, 67, 67),
textTheme: const TextTheme(
displaySmall: TextStyle(fontSize: 40, color: Colors.white),
bodyLarge: TextStyle(
fontWeight: FontWeight.bold, color: Colors.white, fontSize: 16),
),
);
ColorScheme.fromSeed
seedColor에 입력한 색상을 기반으로 Material에서 서로 잘 어울리는 색상을 조합하여 제공해준다.
brightness: Brightness.dark
이 코드가 있어야 darkThem을 다크모드로 인식하여 사용할 수 있다.
TextThem 클래스
- Matreial에서 제공하는 텍스트 테마이다. 미리 만들어둔 스타일들을 가져다가 사용할 수 있게 해두었다(재가공도 가능).
- 어떤 스타일들이 있는지는 아래의 flutter 사이트에서 친절하게 설명해준다
TextTheme class - material library - Dart API
Material design text theme. Definitions for the various typographical styles found in Material Design (e.g., labelLarge, bodySmall). Rather than creating a TextTheme directly, you can obtain an instance as Typography.black or Typography.white. To obtain th
api.flutter.dev
사용 방법
return Container(
height: 200,
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(20),
),
);
이제 원하는 곳에 Theme.of(context)를 사용하여 them.dart 파일에 미리 설정해둔 객체를 가져다가 사용하면 된다(텍스트 객체는 Theme.of(context).textThem 사용) 그럼 시스템 설정에 따라서 자동으로 지정해둔 라이트모드와 다크모드의 설정대로 잘 변경되는 것을 확인할 수 있다.
그런데 사진과 같이 Theme.of(context) 뒤에 . 만 찍어도 미리 제공해주는 객체들이 쫙 뜨게 된다. 이때 ' 뭐지... ? 난 내가 설정해둔 객체만 나올 줄 알았는데...? ' 하면서 순간 뇌정지가 올수도 있으나 안심해도된다. 내가 them.dart 파일에 미리 해당 키워드의 객체를 재가공 해두었다면, 재가공 된 객체를 가져와서 사용하게 된다. + 그리고 물론 Matreial 에서 제공해주는 객체들도 잘 활용하여 편리하게 잘 사용하면 된다.
.copyWith()
만약 기본적으로 제공해주는 객체 또는 them.dart 파일에 지정해둔 객체를 특정 부분에서만 속성을 약간 변경해서 사용하고 싶다면 copyWith()를 사용하면된다. copyWith()를 사용하면 원복 객체를 변경하지 않고, 특정 값만 바꾼 새로운 객체를 반환할 수 있다.
예시
them.dart파일에서 지정해둔 TextThem의 bodyLarge 요소의 fontsize가 16인데, 특정 부분에서만 18로 사용하고 싶다면 아래와 같이 copyWith()의 소괄호 안에 원하는 대로 커스텀 코드를 넣어서 사용하면 된다.
var rowTitleTextStyle =
Theme.of(context).textTheme.bodyLarge!.copyWith(fontSize: 18);