
각 화면들이 공통적으로 가지고 있는 요소가 무엇이 있을까? 기본적으론 배경색, 내비게이션 바를 꼽을 수 있을 것이다.
근데 여기에서 이제 내비게이션 바는 제작을 완료했으니 배경색을 다 적용해 주면 된다.
허나 화면 하나하나 마다 배경색을 일일이 적용시키는 것은 상당히 비효율 적일 것이다. 그러므로 공통적으로 사용하는 기능이나 레이아웃을 묶어둔 기본 뼈대 클래스를 제작해 줄 것이다.
맨 처음 프로젝트 구조화를 했을 때 트리를 아래와 같이 만들어 놨었다.
lib/
├─ constant/
├─ controllers/
├─ screens/
│ ├─ components/
│ ├─ widgets/
└─ main.dart
여기에서 이제 widgets/안에 파일을 만들면 된다.
Flutter에서 화면의 배경 색, backgroundColor를 설정하려면 무엇을 해야 할까? 바로 가장 기본이 되는 위젯 Scaffold를 사용해 주면 될 것이다.
근데 앞서 말했듯이 모든 화면에 Scaffold위젯을 사용하고 파라미터로 붙어 있는 backgroundColor를 일일이 매우 비효율 적이기 때문에 이것을 위젯으로 만들어 줄 것이다.
파일 이름은base_scaffold.dart로 했다.
import 'package:clock_app/constant/color.dart';
import 'package:flutter/material.dart';
class BaseScaffold extends StatelessWidget {
final Widget body;
const BaseScaffold({super.key, required this.body,});
@override
Widget build(BuildContext context) {
final mediaWidth = MediaQuery.sizeOf(context).width;
return Scaffold(
backgroundColor: kBackgroundColor,
body: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
child: SizedBox(
width: mediaWidth,
child: body,
),
),
);
}
}
이제 BaseScaffold()라는 이름의 클래스를 불러올 수 있게 된다. 근데 여기서 끝이 아니다. 위의 사진을 봐보면 공통적인 요소가 하나 더 있는데 바로 앱 바의 햄버거 아이콘 부분이다. 근데 이렇게 말할 수 있다.

"이거 사용되는 화면이 두 개 밖에 없는데 이게 어떻게 공통 요소임? 이거 분류 할꺼면 widgets/가 아니라 components/로 가야 하는거 아님?" 라면서 말이다.
근데 사용하는 곳이 두 곳이나 있으면 사실 공통 요소가 맞기 때문에 그냥 넣었다.
그렇다면 바로 만들어놓은 BaseScaffold에 appBar 파라미터를 추가해 주자.
import 'package:clock_app/constant/color.dart';
import 'package:flutter/material.dart';
class BaseScaffold extends StatelessWidget {
final Widget body;
final PreferredSizeWidget? appBar;
const BaseScaffold({
super.key,
required this.body,
this.appBar,
});
@override
Widget build(BuildContext context) {
final mediaWidth = MediaQuery.sizeOf(context).width;
return Scaffold(
appBar: appBar,
backgroundColor: kBackgroundColor,
body: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 16,
),
child: SizedBox(
width: mediaWidth,
child: body,
),
),
);
}
}
만들면서 처음 알았는데 처음에 appBar 인자를 만들면서 자연스럽게 클래스를 AppBar로 했다만 오류가 나서 그제서야 코드에 보이는 것처럼 PreferredSizeWidget으로 바꿔줬다. 그렇다. 놀랍게도 앱바는 앱바 클래스가 아닌 것이다.
근데 보면 알겠지만 앱 바를 인자값으로 넘겨버렸다. 왜냐하면 이제 이 화면, BaseScaffold는 이미 제 할일을 끝냈기 떄문에 다른 파일로 역할을 분담해주는 것이다.
그렇게 역할이 분담된 앱바는 base_app_bar.dart라는 이름으로 만들어주었다.
import 'package:clock_app/constant/color.dart';
import 'package:flutter/material.dart';
class BaseAppBar extends StatelessWidget implements PreferredSizeWidget{
final VoidCallback onTap;
const BaseAppBar({super.key, required this.onTap});
@override
Widget build(BuildContext context) {
return AppBar(
toolbarHeight: 88,
backgroundColor: kBackgroundColor,
actionsPadding: EdgeInsets.symmetric(
horizontal: 24,
),
actions: [
GestureDetector(
onTap: onTap,
child: Icon(Icons.more_vert),
),
],
);
}
@override
Size get preferredSize => const Size.fromHeight(88);
}
크기는 앞서 Figma에서 만들었던 것 처럼 세로 88, 양옆으로 패딩 24를 주었다.
또 신기한 것이 앱바를 위젯으로 만들려면 아래에 @override되어 있는 것 같이 dpreferredSize를 지정해줘야 한다. (안 그러면 오류 남)
이제 사용은 아래와 같이 해주면 된다.
@override
Widget build(BuildContext context) {
return BaseScaffold(
appBar: BaseAppBar(onTap: () {},),
body: Column(),
);
}
'공부용 프로젝트 > Clock_App' 카테고리의 다른 글
| Clock_App / 공통 사항 추가 디자인 (0) | 2025.10.24 |
|---|---|
| Clock_App / 색상 정의하기 (0) | 2025.10.24 |
| Clock_App / 프로젝트 구조화 (0) | 2025.10.07 |
| Clock_App / 내비게이션 바 디자인하기 (0) | 2025.10.07 |
| Clock_App / 프로젝트 개요 (0) | 2025.10.07 |