Stateless Widget

A widget is either stateful or stateless. If a widget can change—when a user interacts with it, for example—it’s stateful.

A widget that does not require mutable state. That means stateless widgets are immutable. A StatelessWidget will never rebuild by itself. Once it is rendered on the screen, it acts like constant UI that means the widget never changes its appearence during the lifetime of the widget.

A stateless widget never changes. Icon, IconButton, and Text are examples of stateless widgets. Stateless widgets subclass StatelessWidget.

A stateful widget is dynamic: for example, it can change its appearance in response to events triggered by user interactions or when it receives data. Checkbox, Radio, Slider, InkWell, Form, and TextField are examples of stateful widgets. Stateful widgets subclass StatefulWidget.

A widget’s state is stored in a State object, separating the widget’s state from its appearance. The state consists of values that can change, like a slider’s current value or whether a checkbox is checked. When the widget’s state changes, the state object calls setState(), telling the framework to redraw the widget.

Here is the syntax of creating a Stateless widget -

class WidgetName extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Return Widget from this method
  }
}

To create a stateless widget you need to extend StatelessWidget class and within this class you need to override the method build, which is responsible for painting the UI. This build method must return a Widget.

Creating a stateful widget

Implementing a custom stateful widget requires creating two classes:

Here is the syntax for creating a stateful widget -

class WidgetName extends StatefulWidget {
	// This class is the configuration for the state. It holds the
  	// values (in this case nothing) provided by the parent and used
  	// by the build  method of the State. Fields in a Widget
  	// subclass are always marked "final".

	@override
  	_WidgetNameState createState() => _WidgetNameState();
}

class _WidgetNameState extends State<WidgetName> {
	// Here define all your state --

	@override
  	Widget build(BuildContext context) {
  		// Return Widget from here -
  	}
}

First you need to extend the class StatefulWidget and inside the class you must create state by calling createState() method. This method is defined in the State class.

_WidgetNameState createState() => _WidgetNameState();

In the next step, you need to create a state object for the widget. The naming convention of the state object of the stateful widget is starts with an underscore and then the widget name and followed by the word State. For example, if the widget name is WidgetName the state class for the widget should be named as _WidgetNameState, and if the widget name is MyButton then the state class for the widget should be named as _MyButtonState. To create a state object for the widget you need to extend the class State and within less than (<) and greater than (>) sign you need to write the widget name.

class _WidgetNameState extends State<WidgetName> {

Inside the state class for the object, you need to define all your states or custom methods. This is the place where you must override the build method which draws the UI. The build method must return Widget.

Here is an example of Stateful widget -

class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _counter = 0;

  void _increment() {
    setState(() {
      // This call to setState tells the Flutter framework that
      // something has changed in this State, which causes it to rerun
      // the build method below so that the display can reflect the
      // updated values. If you change _counter without calling
      // setState(), then the build method won't be called again,
      // and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called,
    // for instance, as done by the _increment method above.
    // The Flutter framework has been optimized to make rerunning
    // build methods fast, so that you can just rebuild anything that
    // needs updating rather than having to individually change
    // instances of widgets.
    return Row(
      children: [
        RaisedButton(
          onPressed: _increment,
          child: Text('Increment'),
        ),
        Text('Count: $_counter'),
      ],
    );
  }
}

You might wonder why StatefulWidget and State are separate objects. In Flutter, these two types of objects have different life cycles. Widgets are temporary objects, used to construct a presentation of the application in its current state. State objects, on the other hand, are persistent between calls to build(), allowing them to remember information.