이 프로젝트는 개발하는남자님의 유튜브 영상을 참고하여 제작하였습니다. 허나, 원본 영상에서 제작하는 방법과는 다를 수 있습니다.
저번까지는 바텀 네비게이션을 구축했습니다. 이제 UI를 만들어야하는데, 가장 처음인 Home 화면의 앱바를 만들도록 하겠습니다. 일단 Home 화면은 어떤 구성요소로 구성되어있는지 완성된 UI를 보면서 확인하겠습니다.
화면에는 가장 상단에 AppBar가 있고, 바로 아래에는 스토리 영역이 존재합니다. 그리고 여러 사람들의 피드들을 볼 수 있고, 챗 버튼을 눌렀을 때는 하단의 댓글을 볼 수 있는 모달이 등장합니다. 그 중에서 AppBar를 먼저 만들거에요. 그러면 단계별로 가볼까요?
![]() |
![]() |
![]() |
이제 home.dart파일을 생성하고 Home 클래스를 Stateless Widget으로 생성하겠습니다. 이후에 app.dart에서 0번 인덱스에 해당하는 위젯을 Home으로 바꾸어주세요. 앞에 const 키워드를 붙이면 앱의 퍼포먼스가 더 향상됩니다.
앱바에는 앱의 로고가 있고, 오른쪽에는 여러가지 옵션 버튼들이 존재합니다. 간단하게 AppBar위젯으로 제작할 수 있어요.
class Home extends StatelessWidget {
const Home({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//로고
title: ImageData(
path: ImagePath.logo,
width: 300,
),
actions: [
//옵션 버튼들
GestureDetector(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(15.0),
child: ImageData(path: ImagePath.active),
),
),
GestureDetector(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(15.0),
child: ImageData(path: ImagePath.dm),
),
),
],
),
);
}
근데, 이렇게 제작하면 금방 만들지만, 인스타그램의 앱바는 IOS 유저들은 스크롤링 시 페이드 애니메이션이 발동합니다. 아래로 스크롤하면 앱바가 위로 사라지고, 위로 다시 스크롤하면 다시 나타나죠. 그래서 이거를 구현해볼까 합니다. Flutter에서는 SliverAppBar를 사용하면 쉽게 해당 애니메이션 효과를 줄 수 있어요. 다만, SliverAppBar를 사용하기 위해서는 CustomScrollView위젯을 사용해야 합니다. 원래는 이론적인 설명이 더 필요하지만, 그 내용은 후에 Flutter 기본 시리즈에서 다루겠습니다. Scaffold의 body에 CustomScrollView위젯을 전달해주세요. 그리고 SliverAppBar를 넣어주겠습니다.
class Home extends StatelessWidget {
const Home({super.key});
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
_appBar(),
],
),
);
}
// SliverAppBar
Widget _appBar() {
return SliverAppBar(
//floating 옵션을 통해서 페이드 애니메이션 구현 가능
floating: true,
title: ImageData(
path: ImagePath.logo,
width: 300,
),
actions: [
GestureDetector(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(15.0),
child: ImageData(path: ImagePath.active),
),
),
GestureDetector(
onTap: () {},
child: Padding(
padding: const EdgeInsets.all(15.0),
child: ImageData(path: ImagePath.dm),
),
),
],
);
}
}
신기하게도 CustomScrollView는 앱바를 Slivers라는 영역에 다른 위젯들과 함께 전달해야합니다. SliverAppBar에는 floating 프로퍼티가 존재합니다. 해당 프로퍼티는 불리언값을 전달 받으며 true를 전달하면 우리가 원하는 애니메이션을 표현할 수 있어요. 해당 애니메이션을 확인하기 위해서는 body영역에 아이템들이 있어야합니다. 임의의 body를 만들고 전달하겠습니다.
...
Widget _body() {
return SliverList.builder(
itemCount: 50,
itemBuilder: (context, index) => Container(
height: 50,
color:
Colors.primaries[Random().nextInt(Colors.primaries.length)],
));
}
해당 위젯은 임의의 색상의 컨테이를 생성하는 ListView.builder와 같은 위젯입니다. CustomScrollView에서는 해당 위젯을 사용해야 에러가 발생하지 않아요.
스크롤효과는 잘 나타나지만, 뭔가 좀 아쉽습니다. 앱바가 저 위의 status bar 영역까지 넘어가지 않도록 전체를 SafeArea로 감싸겠습니다.
class Home extends StatelessWidget {
const Home({super.key});
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
_appBar(),
_body(),
],
),
),
);
}
이렇게 하면 앱바가 화면위로 넘어가는 것을 방지할 수 있습니다.