flutter notched bar 에 box shadow 주기

윤강석·2023년 1월 31일
0

프로젝트를 진행하며 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")
                                ],
                              )
                            ])),
                  )
                ],
              )
            ],
          ),
        ),
      ),

0개의 댓글