Open In App

Flutter – dispose() Method with Example

Last Updated : 04 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Dispose is a method triggered whenever the created object from the stateful widget is removed permanently from the widget tree. It is generally overridden and called only when the state object is destroyed. Dispose releases the memory allocated to the existing variables of the state. It is only used in a stateful widget because you cannot change the state of a stateless widget.

Syntax:

void dispose(){
//...
super.dispose();
//...
}

If you create objects and do not free the memory used by them before their destruction, there is be chance your application will through a memory leakage in the app store or the play store. It is the exit point of the Stateful Widget. Execution of the dispose method is done in the end when the state object has built itself enough times, and now there is no need for it to build again. It is the last stage of a widget lifecycle; after this, a state object is destroyed completely. Situations where you need to call your dispose() method could be turning off the notifications, unsubscribing, shutting off the animations, etc.

Implementation:

Dart
// ignore_for_file: avoid_unnecessary_containers

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
            appBar: AppBar(
              title: const Text('GeeksforGeeks'),
              backgroundColor: Colors.green,
            ),
            body: const FirstScreen()));
  }
}

class FirstScreen extends StatelessWidget {
  const FirstScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Avoid unnecessary containers
    return Container(
        child: Center(
            child: ElevatedButton(
      onPressed: () => Navigator.of(context)
          .push(MaterialPageRoute(builder: (context) => const NewScreen())),
      child: const Text('Move to the next screen'),
    )

            // RaidedButton is deprecated and would be removed in the coming versions.
            // Use ElevatedButton instead.

            // child: RaisedButton(
            //   color: Colors.green,
            //   onPressed: () => Navigator.of(context)
            //       .push(MaterialPageRoute(builder: (context) => const NewScreen())),
            //   child: const Text('Move to next screen'),
            // ),
            ));
  }
}

class NewScreen extends StatefulWidget {
  const NewScreen({Key? key}) : super(key: key);

  @override
  State<NewScreen> createState() => _NewScreenState();
}

class _NewScreenState extends State<NewScreen> {
  TextEditingController textEditingController = TextEditingController();

  @override
  void dispose() {
    textEditingController.dispose();
    // ignore: avoid_print
    print('Dispose used');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('New Screen'),
        backgroundColor: Colors.green,
      ),
      // Avoid unnecessary containers
      body: Container(
          child: const Center(
        child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 20.0),
            child: Text('This is the new screen')),
      )),
    );
  }
}


Output:

In the above example, the dispose method is called only and only once we exit the new screen.
 



Next Article
Article Tags :

Similar Reads