[Flutter] Dialog 위젯 안에서의 상태 변경(StatefulBuilder)

김민서·2023년 8월 21일
0

가림 치료 앱 개발

목록 보기
1/6

StatefulBuilder

StatefulBuilder 공식 문서

사용자가 새로운 아이패치를 추가하는 단계에서 사용자 정보를 입력할 때 이 위젯을 사용하게 되었다.
예를 들어 나는 아이패치의 좌우 착용 비율을 설정할 때 Slider 위젯을 사용했는데, 이 때 사용자가 슬라이더를 조정하여 값을 변경하면 슬라이더 양측에 해당 값이 바로바로 변경되게 하고 싶었다. 이렇게!

Slider(
	value: currentSliderValue,
    max: 100,
    divisions: 10,
    onChanged: ((value) {
    	setState(() {
        	currentSliderValue = value;
        });
	});
);

이렇게 setState 함수 안에서 변하는 값(value)를 변수 currentSliderValue에 할당해주었다. 하지만 내가 원했던 것처럼 값이 저렇게 실시간으로 변하지 않았다.
왜 그런지 찾아 보았다.

나는 새로운 아이패치를 추가하는 화면을 AlertDialog 안에서 구현했다. 그런데 Dialog 위젯은 StatelessWidget이라서 말 그대로 상태가 없는 위젯으로, 상태 변화가 필요 없는 화면을 구성할 때 사용한다. 처음 위젯을 그릴 때 한 번만 빌드되는 것이다.
그래서 콘솔에 출력해보면 변수 currentSliderValue의 값은 변하는데, 해당 화면에 보여지는 값은 변하지 않는 것이다.

이를 StatefulBuilder를 사용하여 해결할 수 있었다.

StatefulBuilder의 builder로 전달된 StateSetter 함수는 최상위 State의 setState를 재정의한다. (덮어씌운다.)
즉, StatefulBuilder에서 builder로 전달된 새로운 setState를 통해 StatefulBuilder로 감싼 부분만 재생성하게 되는 것이다.

return AlertDialog(
	content: StatefulBuilder(
    	builder: (BuildContext context, StateSetter setState) {
        	return SingleChildScrollView(
        	 	child: ListBody(
                	children: [
                    	const Text('좌우 착용 비율을 설정하세요.'),
                        Slider(
							value: currentSliderValue,
    						max: 100,
    						divisions: 10,
    						onChanged: ((value) {
    							setState(() {
        							currentSliderValue = value;
        						});
							});
						);
                    ];
                );   
            );
		}); 
   );
);

추가: 또 다른 방법이 있다고 한다. AlertDialog 위젯 자체를 StatefulWidget으로 선언하는 것이다. 아하

0개의 댓글