[담타 - 리팩터링] 테마 및 컬러 관리
자주 쓰이는 값을 한번에 관리하기 위해 혹은 틀리면 안되는 값을 조금 더 엄격하기 위해 상수를 사용한다.
내 프로젝트에서는 아래와 같이 관리했는데, common 폴더에 theme.dart 를 만들고 appTheme 클래스를 이용해서 상수를 설정해주었다.
앱 내의 색이 들어가는 모든 것들에 대해 변수를 만들어주고 거기서 또 할당해주었다.
이렇게 한 이유는 색이 들어가는 모든 것들에 각각의 변수를 주어서 하나의 파일에서 모든 색을 수정할 수 있게 하고 싶어서였다.
// /common/theme.dart
class appTheme {
static const Color mainGreen = Color(0xFF111111);
static const Color white = Colors.white;
static const Color grey = Colors.grey;
// main_page
static const Color bottomNavBackgroundColor = white;
static const Color bottomNavSelectedColor = mainGreen;
static const Color bottomNavUnselectedColor = grey;
// home_page
static const Color buttonAddBackgrounColor = mainGreen;
static const Color buttonAddForegroundColor = white;
static const Color buttonMoreBackgrounColor = mainGreen;
static const Color buttonMoreForegroundColor = white;
...
}
하지만 생각보다 앱 자체에 색이 많이 들어가지 않고 색을 바꿀 일도 많지 않았다.
그리고 앱이 커질수록 변수가 정말 엄청나게 늘어나기 때문에 좋은 방법은 아닌 것 같다.
그럼 어떻게 관리하는게 좋을까?
찾아보니 몇 개가 나온다.
1. ThemeData 만들어서 관리
// source : https://heartbeat.comet.ml/flutter-development-best-practices-3e162765340a
theme: ThemeData(
primarySwatch: Colors.lightBlue,
accentColor: Colors.teal,
fontFamily: ‘Lato’,
textTheme: ThemeData.light().textTheme.copyWith(
title: TextStyle(
fontSize: 20,
fontFamily: ‘Lato’,
fontWeight: FontWeight.bold,
),),)
이렇게 ThemeData 를 따로 저장하거나 바로 MaterialApp에 넣어줄 수도 있다.
2. colors.dart 파일에 상수 만들기
// https://github.com/codefactory-co/flutter-lv2-rest-api/blob/main/lib/common/const/colors.dart
// colors.dart
// 주색상
const PRIMARY_COLOR = Color(0xFF22A45D);
// 글자 색상
const BODY_TEXT_COLOR = Color(0xFF868686);
요즘 듣고 있는 코드팩토리님의 강의에서는 이런식으로 사용했다.
https://aschilken.medium.com/flutter-best-practices-colors-and-textstyles-6e14b06fc3a1
Flutter Best Practices: Colors and TextStyles
global const vs theme — pros and cons
aschilken.medium.com
위 글에서도 Theme의 사용보다는 상수가 낫지 않냐고 한다.
어디에서나 참조하기가 쉽고, 코드의 중복을 막고, 하나의 장소에서 변경하면 모든 곳에서 바뀌고, 또 코드가 짧아진다는 것이 장점이라고 한다.
하지만 위 방식으로는 라이트 모드 / 다크 모드를 만들 때 코드가 더 관리하기 어려워진다는 단점이 있다.
3. 클래스 만들어서 관리하기
https://maruf-hassan.medium.com/handling-flutter-images-like-a-pro-cbd0090ab4b3
Handling Flutter Colors like a Pro
This is Part #4 of the series in Flutter Production Level Development where I teach you all the tips and tricks used in an Industry Level…
maruf-hassan.medium.com
import 'package:flutter/widgets.dart';
Class AppColor {
AppColor._();
static const Color blueColor = Color(0xFF2F39C5);
static const Gradient linearGradient = LinearGradient(
begin: Alignment(0.0, 0.0),
end: Alignment(0.707, -0.707),
colors: [
Color(0xffff9a9e),
Color(0xfffad0c4),
Color(0xfffad0c4),
],
);
}
여기서는 /constants/colors.dart 에 AppColor 클래스를 만들어서 관리한다.
AppColor._() 생성자는 private constructor로 인스턴스화를 막아준다.
클래스 내의 변수들을 static으로 선언해주어서 인스턴스를 만들 필요를 없게 한다.
4. ChatGPT에게 물어보기
그렇다고 한다.
결론
후에 라이트모드 / 다크모드 지원 혹은 유저에 의한 색 변경 기능까지 생각하면 ThemeData를 쓰는게 맞는 것 같다.
대신 내가 자주 쓰는 색 등은 따로 상수로 뺄 계획이다.
색이 많이 필요할 경우 결국 앱 전체가 아닌 기능별로 ThemeData와 color를 지정해서 써야한다.
flutter에서 만든 프로젝트를 참고해보자.
https://github.com/flutter/gallery/tree/main/lib
GitHub - flutter/gallery: Flutter Gallery is a resource to help developers evaluate and use Flutter
Flutter Gallery is a resource to help developers evaluate and use Flutter - GitHub - flutter/gallery: Flutter Gallery is a resource to help developers evaluate and use Flutter
github.com
추가로 도움이 되는 블로그
https://mechurak.github.io/2022-10-10_flutter-theme/
flutter에서 theme 사용 및 TextStyle, Color 관리
Color, TextStyle을 앱 전체에서 일관되게 적용을 위해 Theme을 사용하자.
mechurak.github.io
결과
구글의 gallery 프로젝트와 비슷하게 구현했다.
자주 사용하는 상수가 있는 colors.dart와 ColorScheme을 이용하여 만든 themeData로 구성된다.
사용할 때는 Theme.of(context).colorscheme.primary와 같이 사용한다.
다만 함수를 통해 위젯을 렌더링하는 경우 context가 없어서 사용이 불가능한데 이 때는 상수를 써줬다.
추후에 리팩터링을 통해 로직을 개선시키면서 다시 생각해봐야할 것 같다.