Dialog

devkwon·2023년 2월 23일
0

(Cupertino)AlertDialog

사용자에게 현재 어떠한 상태에 있음을 알릴 때 사용한다.

title: 제목 ,content: 내용, shape: 모양 등과 같은 옵션을 지정할 수 있다.

버튼에 따라 액션을 넣어서 해당 버튼을 클릭하였을 때 특정 행위를 수행할 수 있다.

크기는 child의 크기에 비례하여 조절된다.

SimpleDialog

다양한 옵션이 필요할 때 사용하는 dialog이다.

선택은 주로 SimpleDialogOption으로 하게 되는데 onPressed 콜백이 있어서 클릭했을 시 원하는 이벤트를 실행할 수 있다.

deafult로 Padding이 들어가 있다.

Future<void> _askedToLead() async {
  switch (await showDialog<Department>(
    context: context,
    builder: (BuildContext context) {
      return SimpleDialog(
        title: const Text('Select assignment'),
        children: <Widget>[
          SimpleDialogOption(
            onPressed: () { Navigator.pop(context, Department.treasury); },
            child: const Text('Treasury department'),
          ),
          SimpleDialogOption(
            onPressed: () { Navigator.pop(context, Department.state); },
            child: const Text('State department'),
          ),
        ],
      );
    }
  )) {
    case Department.treasury:
      // Let's go.
      // ...
    break;
    case Department.state:
      // ...
    break;
    case null:
      // dialog dismissed
    break;
  }
}

Show(Cupertino)Dialog

dialog를 보여주는데 사용되는 함수. 해당 함수는 context와 builder를 통해 원하는 내용을 보여준다.

만들어진 dialog는 ModalBarrier를 통해 배경화면을 흐리게 한다.

만들어진 dialog위젯은 만든 위젯과 context를 공유하지 않는다. 따라서 동적으로 업데이트하기 위해서는 StateBuilder 나 CustomStatefulWidget을 사용해야 한다.

context argument는 dialog를 위한 Navigator와 Theme를 찾기 위해서 사용된다. 메소드가 호출 될 때만 사용된다. 해당 위젯은 dialog가 종료되기 전에 트리에서 안전하게 삭제된다.

Arguments

barrierDismissed: barrier를 탭하는 경우 dialog를 종료시킬 지 말지 결정한다. true(default)면 종료 false면 종료되지 않는다.

barrierColor: modal barrier의 색상을 정한다. (default:Colors.black54)

useSafeArea: dialog를 OS가 사용하지 않는 안전한 영역에만 display할지 결정한다. true(default)라면 dialog가 OS 영역에 overlap되지 않는다. false라면 스크린 사이즈 제한만 받는다.

userRootNavigator: 주어진 것들 중 가장 가까운 context를 Navigator에 push할지 결정한다. true(default)라면 dialog route를 만들어 root navigator에 넣는다.

routeSettings: showGeneralDialog로 전달되어 dialog의 route를 만드는데 사용된다.

anchorPoint: DisplayFeature는 screen을 sub-screen들로 나눌 수 있게 한다. anchorPoint와 가장 가까운 하나가 content를 render하기 위해 사용된다. 만약 anchorPoint가 없다면 TextDirection.ltr,rtl에 따라 Offset.zero 또는 Offset(doub.maxFinite, 0)이 주어진다. 또한 Direcionality ancestor위젯이 트리 안에 없다면 debug mode에서 assert를 낸다. 리턴으로 dialog가 닫힐 때 Navigator.pop에서 받은 값을 계산하여 Future로 준다.

Future<void> _showMyDialog() async {
  return showDialog<void>(
    context: context,
    barrierDismissible: false, // user must tap button!
    builder: (BuildContext context) {
      return AlertDialog(
        title: const Text('AlertDialog Title'),
        content: SingleChildScrollView(
          child: ListBody(
            children: const <Widget>[
              Text('This is a demo alert dialog.'),
              Text('Would you like to approve of this message?'),
            ],
          ),
        ),
        actions: <Widget>[
          TextButton(
            child: const Text('Approve'),
            onPressed: () {
              Navigator.of(context).pop(); //pop을 하면 종료된다.
            },
          ),
        ],
      );
    },
  );

StatefulBuilder

dialog에서 상태가 변해 rebuild해야하는 경우 StatefulBuild를 사용하면 builder를 통해 setState를 전달하여 해당 부분에만 독립적으로 rebuild가 일어나도록 할 수 있다.

await showDialog<void>(
  context: context,
  builder: (BuildContext context) {
    int? selectedRadio = 0;
    return AlertDialog(
      content: StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: List<Widget>.generate(4, (int index) {
              return Radio<int>(
                value: index,
                groupValue: selectedRadio,
                onChanged: (int? value) {
                  setState(() => selectedRadio = value);
                },
              );
            }),
          );
        },
      ),
    );
  },
);

State Restoration in Dialogs

dialog는 상태 복원이 불가능한데, NAvigator.restorablePush나 Navigator.restorablePushNamed를 DialogRoute와 같이 사용하여 상태 복원을 구현할 수 있다.

0개의 댓글