[Flutter #5] Flutter 위젯 정리 (AppBar · Icon · ClipRRect · Container · AspectRatio · ListView )

도경원's avatar
Sep 26, 2025
[Flutter #5] Flutter 위젯 정리  (AppBar · Icon · ClipRRect · Container · AspectRatio · ListView )

1. AppBar

개념
상단 바 UI로, 보통 leading(좌측), title(중앙), actions(우측) 영역으로 구성됩니다.
핵심 포인트
  • leading: 뒤로가기, 햄버거 버튼 등
  • title: 페이지 제목/검색창
  • actions: 아이콘 버튼들(검색, 알림, 프로필 등)
  • 디자인 요소: backgroundColor, elevation, centerTitle
예제
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; AppBar _buildRecipeAppBar() { return AppBar( backgroundColor: Colors.white, elevation: 1.0, actions: [ Icon(CupertinoIcons.search, color: Colors.black), SizedBox(width: 15), Icon(CupertinoIcons.heart, color: Colors.redAccent), SizedBox(width: 15), ], ); }
  • iOS 느낌 원하면 CupertinoIcons, 머티리얼 느낌이면 Icons 사용.
  • 액션 버튼은 IconButton을 쓰면 onPressed 핸들링이 편해요.

2. Icon

개념
아이콘을 그리는 위젯. Material Icons(기본) 또는 CupertinoIcons(iOS 스타일)를 사용.
핵심 포인트
  • Icon(Icons.home) / Icon(CupertinoIcons.search)
  • 색상, 크기: color, size
짧은 스니펫
Row( children: const [ Icon(Icons.star, size: 28), SizedBox(width: 12), Icon(CupertinoIcons.heart, color: Colors.redAccent, size: 28), ],

3. ClipRRect

개념
사각형 모서리를 둥글게 잘라서(child를) 표시합니다.
핵심 포인트
  • borderRadius로 둥근 정도 설정
  • shape나 decoration 속성이 없으면 사용가능 (Container 위젯은 decoration 속성이 있어서 사용할 필요가 없다)
예제
ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.asset( 'assets/images/coffee.jpeg', fit: BoxFit.cover, ), )

4. Container

개념
“빈 박스” 위젯. 크기, 패딩/마진, 배경색, 테두리, 둥근 모서리 등 스타일을 줄 때 사용.
핵심 포인트
  • 자식이 없으면 가능한 크게, 자식이 있으면 자식 크기에 맞춤
  • 스타일은 decoration으로 설정 (BoxDecoration)
예제
Widget _buildMenuItem(IconData mIcon, String text) { return Container( width: 60, height: 80, decoration: BoxDecoration( borderRadius: BorderRadius.circular(30), border: Border.all(color: Colors.black12), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(mIcon, color: Colors.redAccent, size: 30), SizedBox(height: 5), Text(text, style: TextStyle(color: Colors.black87)), ], ), ); }
  • 단순 여백만 필요하면 SizedBox가 더 가볍고 좋아요.
  • 배경색/테두리/그라데이션 등 스타일이 필요하면 Container.

5. AspectRatio

개념
자식의 가로세로 비율을 유지하게 하는 레이아웃 위젯.
핵심 포인트
  • 비율은 width : height. 예) aspectRatio: 16/9
  • 부모 제약을 고려해 허용 가능한 가장 큰 너비를 쓰고, 높이는 비율로 계산
예제
AspectRatio( aspectRatio: 2 / 1, // 가로:세로 = 2:1 child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Image.asset('assets/images/pizza.jpeg', fit: BoxFit.cover), ), )
직관 예시
화면 너비 300, 비율 2:1 → 높이 = 300 / 2 = 150

6. ListView

개념
스크롤 가능한 Column. 가장 흔한 스크롤 리스트.
핵심 포인트
  • 방향: 기본 세로(scrollDirection: Axis.vertical), 가로도 가능
  • 많은 아이템은 ListView.builder 사용 (성능)
  • Column → 스크롤 필요하면 ListView로 변경
예제
notion image
notion image
ListView( padding: const EdgeInsets.symmetric(horizontal: 20), children: const [ // 왼쪽 정렬은 기본 // CrossAxisAlignment는 ListView에 없음 (Column에서 쓰던 것) // 아이템들... ], )

7. Font 적용 (Google Fonts & 로컬 폰트)

문제점 정리
fontFamilyString을 받습니다. GoogleFonts.patuaOne()TextStyle을 반환하므로 그대로 넣으면 타입 에러가 납니다.
옵션 A) Google Fonts 간편 적용
import 'package:google_fonts/google_fonts.dart'; MaterialApp( theme: ThemeData( // 전체 기본 폰트로 fontFamily: GoogleFonts.patuaOne().fontFamily, // 또는 텍스트테마로 일괄 적용 // textTheme: GoogleFonts.patuaOneTextTheme(), ), home: RecipePage(), );
옵션 B) 로컬 폰트 등록
  1. 폰트 파일 추가: assets/fonts/PatuaOne-Regular.ttf
  1. pubspec.yaml
flutter: uses-material-design: true assets: - assets/ fonts: - family: PatuaOne fonts: - asset: assets/fonts/PatuaOne-Regular.ttf
  1. 적용
ThemeData(fontFamily: 'PatuaOne')
  1. 변경 후 flutter pub get + Hot restart(완전 재시작) 필요

8. 실전 카드 컴포넌트 (재사용)

개념
같은 UI에 다른 데이터를 바인딩하려면 생성자로 값만 바꿔 넣으면 됩니다.
예제
class RecipeListItem extends StatelessWidget { final String imageName; final String title; const RecipeListItem(this.imageName, this.title, {super.key}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset("assets/images/$imageName.jpeg", fit: BoxFit.cover), SizedBox(height: 10), Text(title, style: const TextStyle(fontSize: 20)), Text( "Have you ever made your own $title? " "Once you've tried a homemade $title, you'll never go back.", // 오탈자 homemade 보정 style: const TextStyle(color: Colors.grey, fontSize: 12), ), ], ), ); } }
문법 팁
  • $변수 → 문자열 보간(String interpolation)
  • const를 적절히 쓰면 리빌드/성능에 도움

9. 이름 규칙: _ 언더스코어

개념
Dart에서 식별자 앞의 _라이브러리 프라이빗(private) 의미입니다.
메서드/변수/클래스 앞에 _를 붙이면 해당 파일(라이브러리) 외부에서 접근 불가.
예제
// 같은 파일 내에서는 자유롭게 호출 AppBar _buildRecipeAppBar() => AppBar();
Share article

Gyeongwon's blog