본문 바로가기
CODE/Flutter

[Flutter] Dialog 안에서 SetState 수행하기

by Nuridal_class 2023. 9. 20.
728x90
728x90

 Dialog 안에서 새로고침(SetState) 수행하기

대부분 어떠한 이벤트를 통해서 현재 화면에서 달라진 데이터값을 보여주려면
StatefulWidget를 사용해서 SetState를 이용해 Refresh를 했을 것이다.
그런데 개발하다 보면 Dialog 안에서 변화된 데이터 값을 보여주고 싶을 때가 있는데
SetState를 사용하면 Dialog 밖에 화면을 Refresh 해주기 때문에 변화된 값을 확인할 수 없다.
그래서 이번 포스팅은 Dialog 창안에서 데이터 값이 변화되었을때 
바로 변화가 되어지는 방법에 대해 알아봅시다!

 

간단한 예제 만들기

파일은 main.dart, alter_dialog.dart, basic_button.dart 이렇게 세가지만 만들겠습니다.
내용은 버튼 이벤트시 다이얼로그 창안에서 "골"이라는 버튼을 클릭하면
다이얼로그 안에서 골 득실 숫자가 변하는 것을 해보겠습니다.

 

 1. main.dart

여기에서 보셔야 할 점은 alterDialog를 호출하면서 closePressed 이벤트를 했을 때에는
setState를 사용했다는 점입니다.
class _DialogSetStateState extends State<DialogSetState> {
  int goalCount = 0;
  //📲 표시할 숫자를 초기화 해주는 부분입니다.
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: Text(widget.title, style: const TextStyle(fontSize: 20))),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
              ElevatedButton(
                  onPressed: () => alterDialogSetState(
                      goalCount: goalCount,
                      context: context,
                      closePressed: () {
                        setState(() {
                          Navigator.pop(context);
                        });
                      }),
                      //📲 버튼 이벤트시 alterDialogState를 호출하고
                      //   이때 받는 파라미터들은 goalCount, context, closePressed를 받습니다.
                  child: const Text('Show Dialog SetState'))
            ])));
  }
}

 

 2. alter_dialog.dart

여기가 핵심입니다. 다이얼로그 창안에서 데이터의 변화를 보기 위해서는
StatefulBuilder를 선언해주셔야 합니다.
그리고 StateSetter를 사용하면 다이얼로그 창안에서도 데이터가 바뀌는 것을 확인할 수 있습니다.
alterDialogSetState({
  required BuildContext context,
  required Function() closePressed,
  required int goalCount,
  //📲 필수로 받아와야 하는 파라미터를 정의했습니다.
}) {
  return showDialog(
      context: context,
      builder: (context) => StatefulBuilder(
              builder: (BuildContext context, StateSetter setDialog) {
              //📲 이부분이 핵심입니다. 
              //📲 Dialog창 안에서 데이터 변경의 모습을 보여주려면
              //   "StatefulBuilder를 사용해야 합니다.
              //   새로 고침을 해주는 부분은 "StateSetter setDialog"를 선언해주셔야 합니다.
              //   ※StateSetter는 선언안해줘도 되지만 헷갈리기에 선언해주면 좋습니다.
            return AlertDialog(
              actionsPadding: const EdgeInsets.only(bottom: 5),
              title: const Text('SetDialog Count', textAlign: TextAlign.center),
              content:
                  Row(mainAxisAlignment: MainAxisAlignment.center, children: [
                Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Image.asset(
                      'assets/son.png',
                      width: 120,
                      height: 100,
                    ),
                    //📲 이미지를 불러오는 부분입니다.
                    basicTextButton(
                        buttonText: 'Goal',
                        onPressed: () {
                          setDialog(() {
                            goalCount = goalCount + 1;
                          });
                        }),
                    Text('성공한 goal 개수: $goalCount개')
                    //📲 Goal이란 버튼을 클릭하면
                    //   '성공한 goal 개수: $goalCount개'의 Count가 바뀌는 버튼입니다.
                    //   이때 setState가 아닌 setDialog를 사용해서 데이터가 바뀝니다.
                  ],
                ),
              ]),
              actions: [
                const Divider(thickness: 1.5),
                Center(
                    child: basicTextButton(
                        buttonText: '닫기', onPressed: closePressed)),
              ],
            );
          }));
}

 

 3. basic_button.dart

공통으로 쓰이는 코드가 있다면 여러번 쓰지 않고 따로 선언해두어서
수정할 사항이 있다면 하나만 바꿔도 다른 코드에도 적용이 되도록
관리해 주는 것이 좋습니다.
//📲 자주 쓰인다면 따로 선언해줘서 코드가 중복이 안되게 하는것을 권장합니다.
basicButton({
  required String buttonText,
  required Function() onPressed,
}) {
  return TextButton(
    onPressed: onPressed,
    child: Text(
      buttonText,
      style: const TextStyle(fontSize: 15),
    ),
  );
}

 

실행 결과 화면

실행 결과 화면을 보면 Goal을 누를 때마다 성공한 goal 개수가 늘어난 것을 볼 수 있다.
또한 닫기를 누르고 다시 Show Dialog SetState를 누르면 골 개수가 초기화된 것을 볼 수 있다.
만약에 alter_dialog.dart에서 int goalCount =0을 선언했다면 
dialog를 껐다 켜도 성공한 goal 개수가 초기화되지 않을 것이다.
💡 이유는?
Dialog는 main.dart에서 선언한 것이다.
alter_dialog.dart에서 setDialog는 다이얼로그 안에서만 새로고침을 해주기에
main.dart에서 선언한 다이얼로그는 새로고침이 안된다.
그래서 다이얼로그 자체를 새로고침을 해주고 싶으면 main에서 setState를 해줘야 한다.

flutter dialog setState


👉 개인 github에 아주 간단하지만 그래도 코드를 올려놓았습니다. 사용하실 분들은 사용하셔도 무관합니다.
 

GitHub - Jeoungeunseok/dialogs: flutter에서 여러 Dialog의 사용방법

flutter에서 여러 Dialog의 사용방법. Contribute to Jeoungeunseok/dialogs development by creating an account on GitHub.

github.com

 

이렇게 다이얼로그 안에서 데이터 변화를 보여주는 방법에 대해서 알아보았다.
필자도 처음엔 setState를 막 쓰면서 왜 안되지 이랬던 기억이 있다.
이 글을 보시는 주니어 개발자분들 유용하게 사용하시면 좋겠습니다.
코딩이 쉬워지는 그날까지!!!

728x90
300x250