Open In App

Flutter – Stateful Widget

Last Updated : 01 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

A Stateful Widget has states in it. To understand a Stateful Widget you need to have a clear understanding of widgets and state management.  A state can be defined as “an imperative changing of the user interface” and, a widget is “an immutable description of the part of user interface”. To learn more about them refer to the articles below. 

Based on states, widgets are divided into 2 categories:

  1. Stateless Widget
  2. Stateful Widget

In this article, we will walk you through the Stateful Widgets. 

What are Stateful Widgets?

A Stateful Widget has its own mutable state that it needs to track. It is modified according to the user’s input. A Stateful Widget looks after two things primarily, the changed state based on its previous state and an updated view of the user interface. A track of the previous state value has to be looked at because there is a need to self-rebuild the widget to show the new changes made to your application. A Stateful Widget triggers a build method for creating its children widgets and the subclass of the state holds the related data. It is often used in cases where redrawing of a widget is needed. A Stateful Widget can change when:

  1. There is a User Input included
  2. There are some User Interaction
  3. There are some Dynamic Changes

Given below is the basic structure of a Stateful Widget-

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 Container();
  }
}

The MyApp is a class that extends Stateful Widget. A generic method createState() creates a mutable state for the widget at a particular location and returns another class that is extended by the previous state. The _MyAppState class extends another state. 

Special Methods Associated with Stateful Widget

There are various methods provided by the Stateful class to work with:

1. BuildContext: It provides information regarding which widget is to be built/re-build and where it will be located after re-building. Thus, BuildContext is the widget associated with the state. 

Widget build(BuildContext context) {
    return Container();
  }

2. SetState(): A State object is used to modify the user interface. It executes the code for a particular callback and repaints the widgets that rely on that state for configuration. 

setState(setState(() {
  
});

3. initState(): This method is the entry point of a widget. The initState() method initializes all the methods that the build method will depend upon. This is called only once in a widget’s lifetime and mostly overridden the rest of the time. 

initState() {
    //...
    super.init();
}

4. didChangeDependencies(): It is used for loading the dependencies required for execution of a state. The didChangeDependencies() is called immediately after the initState() is called for the first time and before the triggering of the build method.

void didChangeDependencies() {

 }

5. dispose(): This method is used for removing an object permanently from the widget tree. It is used when we need to clear up the memory by invoking super.dispose().

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

Given below is an example of the Stateful Widget.

Example

Dart




import 'package:flutter/material.dart';
 
void main() {
  runApp(MyApp());
}
 
class MyApp extends StatefulWidget {
  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(
              backgroundColor: Colors.green,
              title: const Text('GeeksforGeeks'),
            ),
            body: const FirstScreen()));
  }
}
 
class FirstScreen extends StatelessWidget {
  const FirstScreen({Key? key}) : super(key: key);
 
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
          child: RaisedButton(
        color: Colors.green,
        onPressed: () => Navigator.of(context)
            .push(MaterialPageRoute(builder: (context) => const NewScreen())),
        child: const Text(
          'Move to next screen',
          style: TextStyle(color: Colors.white),
        ),
      )),
    );
  }
}
 
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
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('GeeksforGeeks '),
        backgroundColor: Colors.green,
      ),
      body: Container(
          child: Center(
        child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 20.0),
            child: Container(
              child: Text(
                'User Interface Changed!!',
              ),
            )),
      )),
    );
  }
}


Output:

In the given example, the user interface changes, and the control shift to the next screen as soon as  the central button is clicked i.e. State of the object is changed. This is exactly what a Stateful Widget is used for. 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads