[Flutter] Dialog 안에서 체크박스를 사용하려면
간단한 UI라 `showDialog` 로 AlertDialog를 만들고 `onChanged` 메소드에서 `setState` 메소드 안에서 체크박스 상태를 변경해주기만 하면됩니다.
하지만 체크박스는 변경되지 않습니다.
이유는 AlertDialog, SimpleDialog 등 *Dialog 류의 위젯들은 StatelessWidget으로 만들어졌기 때문입니다. *Dialog에서 상태 변경을 하려면 Stateful 위젯으로 감싸야합니다. 두가지 방법을 소개합니다.
- StatefulBuilder를 이용하는 방법
- StatefulWidget을 이용하는 방법
위 스크린샷에 있는 체크박스가 있는 AlertDialog 전체 코드입니다.
AlertDialog(
title: Text("CheckBox"),
actions: <Widget>[
Row(
children: [
Row(
children: [
Checkbox(
value: checked,
onChanged: (bool value) {
setState(() {
checked = value;
});
},
),
Text('Agree'),
],
),
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text("Dismiss"),
),
],
),
],
);
새로운 위젯으로 만들지 않고, 최상위 페이지 레벨에서 상태가 있는 *Dialog를 만드려면 StatefulBuilder를 사용합니다.
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return AlertDialog(<생략>);
},
);
},
);
StatefulBuilder를 사용하면 상위 StatefulWidget의 setState를 사용하지 않고 StatefulBuilder가 가지고 있는 setState를 사용합니다. 이 StateSetter를 이용해 다른 StatefulWidget으로 상태를 보낼 수 있게 됩니다.
Dialog를 만들면 항상 코드길이가 길어져 다른 위젯으로 분리해야합니다. 이때 상태가 있는 *Dialog를 사용한다면 StatefulWidget으로 만들면 됩니다.
class CheckBoxAlertDialog extends StatefulWidget {
CheckBoxAlertDialog({Key key}) : super(key: key);@override
_CheckBoxAlertDialogState createState() => _CheckBoxAlertDialogState();
}class _CheckBoxAlertDialogState extends State<CheckBoxAlertDialog> {
bool checked = false;@override
Widget build(BuildContext context) {
return AlertDialog(<생략>);
}
}
StatefulBuilder와 거의 유사하지만 상태를 위젯 스스로 가지고 있는 차이가 있습니다. 상태를 누가 가지고 있어야 하는지에 따라 StatefulBuilder 혹은 StatefulWidget을 선택하면 됩니다.