Flutter에서 Drawer 메뉴 만들기
이번 시간에는 AppBar의 햄버거(☰) 버튼을 클릭했을 때 열리는 Drawer 메뉴를 만들어보자.
아래 이미지를 보면, AppBar 왼쪽의 아이콘을 누르면 사이드 패널이 열리는 UI를 말한다.
Drawer를 사용할 때 주의할 점
Drawer는 내부적으로 AppBar의 왼쪽 영역(leading 부분)을 자동으로 제어하기 때문에 수동으로 지정하면 충돌이 발생.
// ❌ 아래처럼 leading에 IconButton을 추가하면 Drawer가 작동하지 않는다!
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: () {
print("menu button clicked");
},
),
Drawer 샘플 스크린샷 1



Drawer 샘플 코드 1
drawer 속성
- Scaffold의 drawer 속성은 화면 왼쪽에서 열리는 사이드 패널 UI를 정의
- Drawer 안에는 보통 ListView를 사용해서 여러 메뉴를 세로로 나열
padding: EdgeInsets.zero는 상단 잘림 방지용
- 이걸 빼면 Drawer의 헤더가 AppBar 아래에 겹쳐서 보임.
import 'package:flutter/material.dart'; // 데스크탑, 앱 등에 고루 UI를 적용할 수 있게 해주는 구글이 제공해주는 패키
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
// 실질적으로 모든 앱을 감싸고 있다.
title: 'Appbar', // 앱을 총칭하는 이름 -> 스마트 폰 앱에서 최근 사용한 앱 보여줄 때의 이름
theme: ThemeData(primarySwatch: Colors.red // 특정색의 응용들을 기본 색상으로 지정해서 사용하겠
),
home: MyPage(), // home은 앱이 실행될 때 가장먼저 보여주는 페이
);
}
}
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AppBar icon menu'),
elevation: 0.0,
actions: [
// action 속성은 복수의 아이콘 버튼 등을 오른쪽에 배치할 때
IconButton(
// 간단한 위젯이나 타이틀들을 앱바의 왼쪽에 위치시키는 것을 말함
icon: Icon(Icons.shopping_cart), // 아이콘
onPressed: () {
// 버튼을 눌렀을 때
print("shopping_cart is clicked");
},
),
IconButton(
// 간단한 위젯이나 타이틀들을 앱바의 왼쪽에 위치시키는 것을 말함
icon: Icon(Icons.search), // 아이콘
onPressed: () {
// 버튼을 눌렀을 때
print("search is clicked");
},
)
],
),
drawer: Drawer( // 햄버거 버튼으로 사이드바 만드는 코드
child: ListView( // 리스트 뷰 통해서 넣어야 해
padding: EdgeInsets.zero, // 이 코드 중요하다. 이거 없으면 상단 부분이 짤리게 나옴
children: [
UserAccountsDrawerHeader( // Drawer의 헤더쪽에 넣을 코드
currentAccountPicture: CircleAvatar( // 헤더에 넣어줄 이미지
backgroundImage: AssetImage('assets/bbanto.png'),
backgroundColor: Colors.white,
),
accountName: Text('bbanto'), // @require 로 필수 : 이름
accountEmail: Text('testEmail@test.com'), // @require 로 필수 : 이메일
onDetailsPressed: () {
print('Header is clicked');
},
decoration: BoxDecoration( // 데코레이션이라고 해서 박스를 꾸미기
color: Colors.redAccent[200],
borderRadius: BorderRadius.only( // 하단에만 적용하겠다.
bottomLeft: Radius.circular(40.0),
bottomRight: Radius.circular(40.0))),
),
],
),
),
);
}
}
Drawer 샘플 스크린샷 2


좀 더 자세히 볼 부분
3가지 부분을 좀 더 자세히 볼 것
- UserAccountsDrawerHeader에 다른 계정 사진 추가하기
- ListTile을 이용해 Drawer 내부 메뉴 구성하기
- onTap, leading, trailing의 역할 이해하기
샘플 코드 2
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Appbar',
theme: ThemeData(primarySwatch: Colors.red),
home: MyPage(),
);
}
}
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AppBar icon menu'),
elevation: 0.0,
actions: [
IconButton(
icon: Icon(Icons.shopping_cart),
onPressed: () {
print("shopping_cart is clicked");
},
),
IconButton(
icon: Icon(Icons.search),
onPressed: () {
print("search is clicked");
},
),
],
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
UserAccountsDrawerHeader(
currentAccountPicture: CircleAvatar(
backgroundImage: AssetImage('assets/bbanto.png'),
backgroundColor: Colors.white,
),
otherAccountsPictures: [
CircleAvatar(
backgroundImage: AssetImage('assets/chef.png'),
backgroundColor: Colors.white,
),
],
accountName: Text('bbanto'),
accountEmail: Text('testEmail@test.com'),
onDetailsPressed: () {
print('Header is clicked');
},
decoration: BoxDecoration(
color: Colors.redAccent[200],
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40.0),
bottomRight: Radius.circular(40.0),
),
),
),
ListTile(
leading: Icon(Icons.home, color: Colors.grey[850]),
title: Text('Home'),
trailing: Icon(Icons.add),
onTap: () {
print('home is clicked');
},
),
ListTile(
leading: Icon(Icons.settings, color: Colors.grey[850]),
title: Text('QnA'),
trailing: Icon(Icons.add),
onTap: () {
print('settings is clicked');
},
),
ListTile(
leading: Icon(Icons.question_answer, color: Colors.grey[850]),
title: Text('Question'),
trailing: Icon(Icons.add),
onTap: () {
print('question_answer is clicked');
},
),
],
),
),
);
}
}'Flutter > 2.0' 카테고리의 다른 글
| Flutter 2.0에서 ScaffoldMessenger와 SnackBar 변화 정리 (0) | 2021.08.12 |
|---|---|
| Flutter의 BuildContext 알아보기 (0) | 2021.08.11 |
| Flutter에서 AppBar 메뉴 아이콘 추가하기 (0) | 2021.08.10 |
| Dart에서 클래스(Class)와 생성자(Constructor) (0) | 2021.08.10 |
| 캐릭터 페이지 디자인 실습 (0) | 2021.08.10 |