프로젝트를 진행하며 notched navigation bar 에 box-shadow 를 줄 일이 생겼다. 너무 아쉽게도 위젯 자체에서 box-shadow 를 제공하지 않아서 직접 구현해야할 일이 생겼다.
가장 처음 떠올린건 notched bar 를 겹으로 쌓아서(stack 으로) 아래에 깔린 위젯에 gradient color 를 주어 그림자처럼 보이게 하려 했으나 아래에 깔린 bar 위제에 gradient 를 주면 아래처럼 보인다.(바 아래에 검은 배경이 깔린다)
이를 해결하고자 총 세개의 층으로 깔아야했고 가운데 층에 box-shadow의 역할을 할 container 를 깔고 그 위에 다시 notched bar 를 얹어준다. 이때 notched bar 내부에서 overflow 된것들은 hidden 처리 되어서 우리가 원하는 모양이 보존된다. 코드는 아래와 같다.
bottomNavigationBar: BottomAppBar(
clipBehavior: Clip.antiAlias,
shape:
CircularNotchedRectangle(), // ← carves notch for FAB in BottomAppBar
color: Colors.white,
notchMargin: 15,
child: SizedBox(
width: double.infinity,
height: 81,
child: Stack(
children: [
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(colors: [
Color.fromRGBO(50, 50, 50, 0.1),
Color.fromRGBO(50, 50, 50, 0.3)
], begin: Alignment.topCenter, end: Alignment.bottomCenter)),
),
Column(
children: <Widget>[
SizedBox(
height: 1,
),
BottomAppBar(
clipBehavior: Clip.antiAlias,
shape: const CircularNotchedRectangle(),
color: Colors.white,
elevation: 0,
notchMargin: 15,
child: SizedBox(
width: double.infinity,
height: 80,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 10),
IconButton(
padding: EdgeInsets.all(0),
onPressed: () {},
icon: Image.asset(
width: 45,
"assets/images/babyFace@2.png",
)),
Text("Baby Monitor")
],
),
SizedBox(width: 80),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 10),
IconButton(
padding: EdgeInsets.all(0),
onPressed: () {},
icon: Image.asset(
width: 50,
"assets/images/diary.png")),
Text("Diary")
],
)
])),
)
],
)
],
),
),
),