Managing UI Updates with setState
Flutter apps are built from widgets, and many of these widgets need to change over time in response to user interactions or data updates. To handle these dynamic changes, Flutter provides stateful widgets. A stateful widget has a mutable state object that can update its appearance or behavior. The setState method is central to this process: it tells Flutter that the widget's state has changed and the UI should be rebuilt to reflect those changes.
main.dart
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748import 'package:flutter/material.dart'; void main() => runApp(const CounterApp()); class CounterApp extends StatelessWidget { const CounterApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: CounterWidget(), ); } } class CounterWidget extends StatefulWidget { const CounterWidget({super.key}); @override State<CounterWidget> createState() => _CounterWidgetState(); } class _CounterWidgetState extends State<CounterWidget> { int _count = 0; void _incrementCounter() { setState(() { _count += 1; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Counter Example')), body: Center( child: Text( 'Count: $_count', style: const TextStyle(fontSize: 32), ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, child: const Icon(Icons.add), ), ); } }
When you call setState inside a stateful widget, Flutter marks that widget as "dirty" and schedules a rebuild. This means the build method runs again, updating the UI to show the latest state values. In the counter example, pressing the button calls _incrementCounter, which uses setState to increase _count. Flutter then rebuilds the widget, and you see the new count on screen.
main.dart
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950import 'package:flutter/material.dart'; void main() => runApp(const ToggleApp()); class ToggleApp extends StatelessWidget { const ToggleApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: ToggleWidget(), ); } } class ToggleWidget extends StatefulWidget { const ToggleWidget({super.key}); @override State<ToggleWidget> createState() => _ToggleWidgetState(); } class _ToggleWidgetState extends State<ToggleWidget> { bool _showText = true; void _toggleVisibility() { setState(() { _showText = !_showText; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Toggle Example')), body: Center( child: _showText ? const Text( 'Hello, Flutter!', style: TextStyle(fontSize: 28), ) : const SizedBox.shrink(), ), floatingActionButton: FloatingActionButton( onPressed: _toggleVisibility, child: const Icon(Icons.visibility), ), ); } }
Thanks for your feedback!
Ask AI
Ask AI
Ask anything or try one of the suggested questions to begin our chat
Awesome!
Completion rate improved to 9.09
Managing UI Updates with setState
Swipe to show menu
Flutter apps are built from widgets, and many of these widgets need to change over time in response to user interactions or data updates. To handle these dynamic changes, Flutter provides stateful widgets. A stateful widget has a mutable state object that can update its appearance or behavior. The setState method is central to this process: it tells Flutter that the widget's state has changed and the UI should be rebuilt to reflect those changes.
main.dart
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748import 'package:flutter/material.dart'; void main() => runApp(const CounterApp()); class CounterApp extends StatelessWidget { const CounterApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: CounterWidget(), ); } } class CounterWidget extends StatefulWidget { const CounterWidget({super.key}); @override State<CounterWidget> createState() => _CounterWidgetState(); } class _CounterWidgetState extends State<CounterWidget> { int _count = 0; void _incrementCounter() { setState(() { _count += 1; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Counter Example')), body: Center( child: Text( 'Count: $_count', style: const TextStyle(fontSize: 32), ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, child: const Icon(Icons.add), ), ); } }
When you call setState inside a stateful widget, Flutter marks that widget as "dirty" and schedules a rebuild. This means the build method runs again, updating the UI to show the latest state values. In the counter example, pressing the button calls _incrementCounter, which uses setState to increase _count. Flutter then rebuilds the widget, and you see the new count on screen.
main.dart
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950import 'package:flutter/material.dart'; void main() => runApp(const ToggleApp()); class ToggleApp extends StatelessWidget { const ToggleApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: ToggleWidget(), ); } } class ToggleWidget extends StatefulWidget { const ToggleWidget({super.key}); @override State<ToggleWidget> createState() => _ToggleWidgetState(); } class _ToggleWidgetState extends State<ToggleWidget> { bool _showText = true; void _toggleVisibility() { setState(() { _showText = !_showText; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Toggle Example')), body: Center( child: _showText ? const Text( 'Hello, Flutter!', style: TextStyle(fontSize: 28), ) : const SizedBox.shrink(), ), floatingActionButton: FloatingActionButton( onPressed: _toggleVisibility, child: const Icon(Icons.visibility), ), ); } }
Thanks for your feedback!