Flutter StatefulWidget Close

Flutter에서 StatefulWidget을 완전히 종료하고 메모리에서 삭제하려면 다음을 고려해야 합니다.

1. Navigator를 사용하여 제거

일반적으로 화면 이동 시 Navigator.pop(context)를 사용하여 현재 StatefulWidget을 제거하면 됩니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Navigator.pop(context);
Navigator.pop(context);
Navigator.pop(context);

이렇게 하면 현재 위젯이 스택에서 제거되고 dispose()가 호출됩니다.


2. dispose()에서 리소스 정리

만약 StatefulWidget에서 스트림, 타이머, 컨트롤러 등을 사용하고 있다면, dispose()에서 반드시 정리해야 합니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
@override
void dispose() {
myStreamController.close();
myTimer?.cancel();
myAnimationController.dispose();
super.dispose();
}
@override void dispose() { myStreamController.close(); myTimer?.cancel(); myAnimationController.dispose(); super.dispose(); }
@override
void dispose() {
  myStreamController.close();
  myTimer?.cancel();
  myAnimationController.dispose();
  super.dispose();
}

이렇게 하면 위젯이 사라질 때 메모리 누수를 방지할 수 있습니다.


3. SystemNavigator.pop()으로 앱 종료

앱을 완전히 종료하려면 다음을 사용할 수 있습니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
SystemNavigator.pop();
SystemNavigator.pop();
SystemNavigator.pop();

이 방법은 앱 자체를 종료시키므로, 일반적인 위젯 제거와는 다릅니다.


4. StatefulWidget을 강제로 제거 (setState()dispose())

만약 특정 조건에서 StatefulWidget을 강제로 제거하고 싶다면, 부모 위젯에서 setState()를 호출하여 해당 위젯을 트리에서 제거할 수 있습니다.

예제:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _showWidget = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: [
if (_showWidget) MyStatefulWidget(),
ElevatedButton(
onPressed: () {
setState(() {
_showWidget = false; // MyStatefulWidget 제거
});
},
child: Text("위젯 제거"),
),
],
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
void dispose() {
print("MyStatefulWidget disposed");
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
height: 100,
color: Colors.blue,
child: Center(child: Text("StatefulWidget")),
);
}
}
class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { bool _showWidget = true; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Column( children: [ if (_showWidget) MyStatefulWidget(), ElevatedButton( onPressed: () { setState(() { _showWidget = false; // MyStatefulWidget 제거 }); }, child: Text("위젯 제거"), ), ], ), ), ); } } class MyStatefulWidget extends StatefulWidget { @override _MyStatefulWidgetState createState() => _MyStatefulWidgetState(); } class _MyStatefulWidgetState extends State<MyStatefulWidget> { @override void dispose() { print("MyStatefulWidget disposed"); super.dispose(); } @override Widget build(BuildContext context) { return Container( height: 100, color: Colors.blue, child: Center(child: Text("StatefulWidget")), ); } }
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _showWidget = true;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Column(
          children: [
            if (_showWidget) MyStatefulWidget(),
            ElevatedButton(
              onPressed: () {
                setState(() {
                  _showWidget = false; // MyStatefulWidget 제거
                });
              },
              child: Text("위젯 제거"),
            ),
          ],
        ),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  @override
  void dispose() {
    print("MyStatefulWidget disposed");
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 100,
      color: Colors.blue,
      child: Center(child: Text("StatefulWidget")),
    );
  }
}

위 코드를 실행한 후 버튼을 누르면 MyStatefulWidget이 제거되고 dispose()가 호출됩니다.


결론

  • 화면 이동Navigator.pop(context)
  • 리소스 정리dispose()에서
  • 앱 종료SystemNavigator.pop()
  • 강제 제거setState()StatefulWidget을 트리에서 삭제

이 방법들을 조합하여 위젯을 메모리에서 완전히 삭제할 수 있습니다. 🚀

Leave a Reply

Your email address will not be published. Required fields are marked *