아마도 flutter에서 context를 이해하는건 굉장히 멀고도 험한 길인 것 같다.
오늘은 PopupMenuItem를 onTap했을 때, dialog를 열어주는 부분을 구현하였다. 간단하게 onTap에 dialog를 여는 함수를 넣어주었는데, 이상하게도 print 했을 때 콘솔은 찍히는데 dialog가 열리지 않았다.
await showMenu(
context: context,
position: RelativeRect.fromLTRB(
offset.dx,
offset.dy,
MediaQuery.of(context).size.width - offset.dx,
MediaQuery.of(context).size.height - offset.dy
),
items: [
PopupMenuItem(
onTap: () {
modifyPopUp(x, y, z);
},
child: Text("x")
)
]
);
Future modifyPopUp(String x, String y, String z) async {
print("들어오는데?");
return await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
title: Column(
children: <Widget>[
new Text("수정하기"),
],
),
//
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
controller: _modifyController,
)
],
),
actions: <Widget>[
TextButton(
child: new Text("확인"),
onPressed: () {
modifyMemo(x, y, z, _modifyController.text);
},
),
TextButton(
child: new Text("취소"),
onPressed: () {
AppStorage.popNavigator();
},
),
],
);
});
}
한참을 고민했다. 왜 showDialog를 return하지 않을까!
힌트는 PopupMenuItem에 있었다. PopupMenuItem클래스를 살펴보니
@protected
void handleTap() {
widget.onTap?.call();
Navigator.pop<T>(context, widget.value);
}
라는 부분이 있었고, 결국 ontap으로 item을 눌렀을 때 Navigator.pop(context)가 실행된다는 것이었다. 결국 내가 showdialog를 열더라도, Navigator.pop(context)가 실행되면서 dialog가 켜지자마자 꺼지는 바보같은 상황이 발생하는 것이다.
이를 해결하기위해 showdialog를 사용하는 함수 호출시에 WidgetsBinding.instance.addPostFrameCallback 를 감싸주어 성공적으로 함수를 호출 시킬 수 있었다. WidgetsBinding.instance.addPostFrameCallback로 widget이 빌드된 뒤에 콜백이 실행 될 수 있도록 한다는 의미긴 했는데.. 좀 더 공부가 필요할 것 같다.
최종 코드
Future<void> handleRawKeyEvent(TapDownDetails details, String x, String y, String z) async {
print("들어는옴");
tapDownPosition = details.globalPosition;
final offset = details.globalPosition;
await showMenu(
context: context,
position: RelativeRect.fromLTRB(
offset.dx,
offset.dy,
MediaQuery.of(context).size.width - offset.dx,
MediaQuery.of(context).size.height - offset.dy
),
items: [
PopupMenuItem(
onTap: () {
WidgetsBinding?.instance?.addPostFrameCallback((_) {
modifyPopUp(x, y, z);
});
},
child: Text("수정하기")
)
]
);
오늘도 성장했다.. 아마도
'Flutter' 카테고리의 다른 글
[Flutter] UI(1) - copyWith (1) | 2023.12.07 |
---|---|
[Flutter] Widget(3) - Align (1) | 2023.12.07 |
[Flutter] Widget(2) - ListView (1) | 2023.12.06 |
[Flutter] Widget(1) - Dialog, Alert Dialog, Simple Dialog, Show Dialog (0) | 2023.12.05 |
[flutter]플러터에서 Intent로 다른 패키지 실행 시 화면 전환이 안되는 현상 (0) | 2023.10.25 |