Flutter PRO 팁 #0: 시작할 때 대화 상자 열기
위젯이
StatefulWidget
인 경우 다음과 같이 생각했을 수 있습니다.class SomeWidget extends StatefulWidget {
const SomeWidget({Key? key}) : super(key: key);
@override
State<SomeWidget> createState() => _SomeWidgetState();
}
class _SomeWidgetState extends State<SomeWidget> {
@override
void initState() {
super.initState();
// Try to open a dialog in initState()
showDialog(
context: context,
builder: (context) => AlertDialog(
content: const Text('Dialog content'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Accept'),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sample'),
),
body: const Center(
child: Text('Body of the Scaffold'),
),
);
}
}
그러나 다음과 같은 오류가 발생합니다.
======== Exception caught by widgets library =======================================================
The following assertion was thrown building Builder:
dependOnInheritedWidgetOfExactType<_LocalizationsScope>() or dependOnInheritedElement() was called before _PostFrameCallbackSampleState.initState() completed.When an inherited widget changes, for example if the value of Theme.of() changes, its dependent widgets are rebuilt. If the dependent widget's reference to the inherited widget is in a constructor or an initState() method, then the rebuilt dependent widget will not reflect the changes in the inherited widget.
Typically references to inherited widgets should occur in widget build() methods. Alternatively, initialization based on inherited widgets can be placed in the didChangeDependencies method, which is called after initState and whenever the dependencies change thereafter.
이런 일이 발생하는 이유는 해당 위젯이 렌더링 단계에 있기 때문에 대화 상자를 표시하려면 해당 단계가 완료될 때까지 기다려야 합니다. 어떻게 할 수 있습니까? 운 좋게도 WidgetsBinding 클래스에는
addPostFrameCallback
라는 메서드가 있으며, 이 메서드의 documentation은 다음을 알려줍니다.Schedule a callback for the end of this frame.
이 방법을 통해 다음과 같이 현재 프레임의 렌더링이 끝날 때 실행되도록 해당 작업을 '예약'할 수 있습니다.
class PostFrameCallbackSample extends StatefulWidget {
const PostFrameCallbackSample({Key? key}) : super(key: key);
@override
State<PostFrameCallbackSample> createState() =>
_PostFrameCallbackSampleState();
}
class _PostFrameCallbackSampleState extends State<PostFrameCallbackSample> {
@override
void initState() {
super.initState();
WidgetsBinding.instance?.addPostFrameCallback((_) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: const Text('Dialog content'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Accept'),
),
],
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Post Frame Callback sample'),
),
body: const Center(
child: Text('Body of the Scaffold'),
),
);
}
}
이렇게 하면 이 위젯의 수명 주기 시작 시 문제 없이 대화 상자를 표시할 수 있습니다. 실제로 대화 상자를 표시하는 것 외에 UI를 변경해야 하는 다른 작업에도 사용할 수 있습니다.
위젯이
StatelessWidget
인 경우 다음과 같이 FutureBuilder
로 래핑할 수 있습니다.class PostFrameCallbackSampleStateless extends StatelessWidget {
const PostFrameCallbackSampleStateless();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _showDialog(context),
builder: (context, snapshot) => Scaffold(
appBar: AppBar(
title: const Text('Post Frame Callback Stateless'),
),
body: const Center(
child: Text('Body of the Scaffold'),
),
),
);
}
Future<void> _showDialog(BuildContext context) async {
WidgetsBinding.instance?.addPostFrameCallback((_) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: const Text('Dialog content'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Accept'),
),
],
),
);
});
}
}
트리에 새 위젯을 추가할 때 대화 상자를 표시하는 것은 다시는 문제가 되지 않습니다. 😀
이 자습서here의 샘플을 찾을 수 있습니다.
즐거운 코딩하세요!
Reference
이 문제에 관하여(Flutter PRO 팁 #0: 시작할 때 대화 상자 열기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/svprdga/flutter-pro-tip-0-open-a-dialog-at-startup-n5n텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)