[Flutter] PopupMenuButton 를 이용한 드롭다운 버튼 구현 onSelected

2024-01-03


사진: Unsplash 의 NEOM


1. 구현 예제 코드

 

코드를 구현한 배경지식은 로그인 후 Appbar 우측 상단에 톱니모양의 아이콘이 나오면 로그아웃과 회원탈퇴 기능을 하는 드롭다운 버튼을 구현하는 것이 필요하여, PopupMenuButton 위젯을 사용하여 구현하였다.

 

드롭다운은 메뉴는 로그아웃/회원탈퇴 두 가지이며, 각각은 PopupMenuItem 위젯으로 wrapping 되어 있다. 유저의 tap에 따라  onSlected 되면 해당 PopupMenuItemvalue 값 기준으로 분기를 진행하여 원하는 기능을 수행할 수 있게 된다.

 

PopupMenuButton(
    onSelected: (value) async {
      if (value == 'signout') {
        await authService.signOut();
        if (context.mounted) {
          Navigator.pop(context);
          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (context) => const SignIn(), //로그아웃 후 로그인 페이지 이동
            ),
          );
        }
      } else if (value == 'resign') {
        Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => Resign()),  //회원탈퇴 페이지 이동
        );
      }
    },
    color: const Color(0xFF0F095B),
    itemBuilder: (context) => [
      const PopupMenuItem(
        value: 'signout',
        child: Text('로그아웃',
            style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold)),
      ),
      const PopupMenuItem(
        value: 'resign',
        child: Text('회원 탈퇴',
            style: TextStyle(
                color: Colors.white,
                fontWeight: FontWeight.bold)),
      ),
    ],
    child: const Icon(
      Icons.settings,
      color: Colors.white,
    ),
  ),

참고 : 처음에 onSelected 옵션이 있는지 모르고 PopupMenuItem를 GestureDetector를 감싸서 했는데, GestureDetector 기능은 PopupMenuButton에서는 동작하지 않는다. 

2. 출처

 

https://api.flutter.dev/flutter/material/PopupMenuButton-class.html

 

PopupMenuButton class - material library - Dart API

Displays a menu when pressed and calls onSelected when the menu is dismissed because an item was selected. The value passed to onSelected is the value of the selected menu item. One of child or icon may be provided, but not both. If icon is provided, then

api.flutter.dev

 


메인 이미지 출처 : 사진: UnsplashNEOM