팀프로젝트 디자인을 마치고, 본격적인 코딩에 들어갔다.
이런저런 우여곡절도 있었지만, 구현 과정에서는 다들 열심히 임해주었다!

flutter Theme에 대해 궁금증이 생겨 Google 크롤링, Gemini, 네이버, youtube 등 여러 사이트를 뒤져보았다.
youtube를 최신순으로 뒤지던 중, "Debug To Discover" 채널을 알게 되었다.
flutter를 중점으로 올리는 채널인데 Theme Tutorial 영상이 있길래 따라가보기로 했다.
물론 외국인이라.. 자막은 키도록 하겠다.
ThemeData를 단순히 class 하나 안에 lightTheme, darkTheme 두가지를 static으로 몰아넣어 관리했었다.
하지만, 영상에서는 ComponentsTheme, ContentsTheme, Theme Tokens 등 여러 디렉토리에 걸쳐 나눠서 관리하고 있었다.
모든 Theme은 함수로 관리되고 있었는데, 유지보수와 최상단 위젯의 rebuild에 따른 용이함때문인듯 하다.
ComponentsTheme은 ContentsTheme, ButtonTheme, DialogTheme으로 구성되어 있다.
ContentsTheme은 Container, Card, Divider 등 전체적인 Components의 Theme을 관리하며, Dialog는 Modal을 전적으로 관리한다.
ButtonTheme은 당연히 Button을 관리한다.
그럼 어디서 값을 가져와 관리하냐?
Tokens에는 color, text, shadow 등 자주 사용되는 속성값을 담아둔다.
이 Design Token들을 이용해 ColorScheme를 만들고, 이를 통해 Theme을 관리하게 된다.
이제 좀 개념이 잡히는 것 같다.
앱을 더 이쁘게 꾸미게 위해서는 Extension이 필요하다.
말 그대로 테마의 확장 버전이라고 생각하면 된다.
흔히 보이는 그라데이션이 여기에 포함된다.
이 부분은 조금 더 학습이 필요하기에 팀 프로젝트 이후, riverpod과 다시 한번 다루기로 한다.
이번 팀 프로젝트 AppleMarket은 은은한 살구색 느낌의 앱으로 개발하고 싶다.
앱에서 필요로 하는 Widget은 피그마를 통해 정리해두었기에 그에 맞춰 테마를 구현하고자 한다.
class AppColors {
// Light Theme
static const Color lightPrimary = Colors.black;
static const Color lightSecondary = Color(0xFFFF968A);
static const Color lightBackground = Color(0xFFFFC5BF);
static const Color lightSurface = Colors.white;
static const Color lightSurfaceVariant = Color(0xFFF3F4F6);
static const Color lightText = Colors.black;
static const Color lightError = Colors.black54;
// Dark Theme
static const Color darkPrimary = Color(0xFFFFD8BE);
static const Color darkSecondary = Colors.grey;
static const Color darkBackground = Colors.black;
static const Color darkSurface = Color(0xFF736571);
static const Color darkSurfaceVariant = Color(0xFFF3F4F6);
static const Color darkText = Colors.white;
static const Color darkError = Colors.black54;
}
따라서, 주요 컬러는 다음과 같이 설정했다.
Primary는 주요 위젯의 색상, Secondary는 가끔 등장하는 위젯 정도로 생각하면 될 것 같다.
Background와 Surface에 대해 헷갈렸는데, 전자는 앱 전체의 바탕색, 후자는 특정 위젯에 대한 색상이라고 생각하면 된다.
SurfaceVariant는 특정 위젯이 기존 위젯과 다르게 표시되어야 할 때 사용한다.
class ContentsThemes {
static ListTileThemeData listTileTheme(ColorScheme colors) {
return ListTileThemeData(
tileColor: Colors.transparent,
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusGeometry.circular(12),
),
iconColor: colors.onSurface,
textColor: colors.onSurface,
);
}
static DividerThemeData dividerTheme(ColorScheme colors) {
return DividerThemeData(
color: colors.onSurface.withValues(alpha: 0.1),
thickness: 1,
space: 24,
indent: 10,
endIndent: 10,
);
}
static AppBarThemeData appBarTheme(ColorScheme colors) {
return AppBarThemeData(
backgroundColor: Colors.transparent,
centerTitle: true,
titleTextStyle: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
fontFamily: "Dongle",
),
iconTheme: IconThemeData(color: colors.onSurface),
);
}
}
ContentsThemes는 다음과 같이 구성되어 있다.
GoogleFonts 라이브러리를 사용하게 됨으로, 리팩토링이 필요한 상태이다.
내일해야겠다..
첫 팀프로젝트라 ui 구성은 팀원들에게 맡기고 도메인 로직과 테마 관리에 집중하고 있다.
내일은 장바구니 추가 및 삭제 기능과 테마 완료, 추가적으로 시간이 나면 나만의 기능으로 dismissible, GridView 변형까지 해봐야겠다!