CINXE.COM
Handling user input | Flutter
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Handling user input | Flutter</title><link rel="icon" href="/assets/images/branding/flutter/icon/64.png" eleventy:ignore><link rel="apple-touch-icon" href="/assets/images/branding/flutter/logo/flutter-logomark-320px.png" eleventy:ignore><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="theme-color" content="#ffffff"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><meta name="google-site-verification" content="HFqxhSbf9YA_0rBglNLzDiWnrHiK_w4cqDh2YD2GEY4"><script>!function(e,t,a,n){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a);m.async=!0,m.src="https://www.googletagmanager.com/gtm.js?id=GTM-ND4LWWZ",g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer")</script><script>!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",s.parentNode.insertBefore(o,s)}(window,document,"script",0,"ga"),ga("create","UA-67589403-1","auto"),ga("send","pageview")</script><meta name="description" content="Learn how to handle user input in Flutter."><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@flutterdev"><meta property="og:title" content="Handling user input"><meta property="og:url" content="https://docs.flutter.dev/get-started/fundamentals/user-input"><meta property="og:description" content="Learn how to handle user input in Flutter."><meta property="og:image" content="https://docs.flutter.dev/assets/images/flutter-logo-sharing.png" eleventy:ignore><link href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" rel="stylesheet"><script>window.__CALLBACKS=[]</script><link rel="stylesheet" href="/assets/css/main.css?v=4"></head><body><section id="cookie-notice"><div class="container"><p>docs.flutter.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic. <a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a>.</p><button id="cookie-consent" class="filled-button">OK, got it</button></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-ND4LWWZ" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="site-banner" role="alert"><p>Flutter 3.29 is here with a bouquet of performance and fidelity improvements for your apps! <a href="https://medium.com/flutter/whats-new-in-flutter-3-29-f90c380c2317">Learn more</a><br></p></div><header class="site-header"><a href="#document-title" id="skip-to-main" class="filled-button" tabindex="1">Skip to main content</a><nav class="navbar"><div id="site-switcher" class="dropdown"><button class="dropdown-button site-wordmark" aria-expanded="false" aria-controls="site-switcher-menu" aria-label="Switch between Flutter and Dart sites"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span> <span class="subtype">Docs</span> <span class="material-symbols" aria-hidden="true">unfold_more</span></button><div class="dropdown-content" id="site-switcher-menu"><nav class="dropdown-menu" role="menu"><ul><li role="presentation"><a href="https://flutter.dev" class="site-wordmark" role="menuitem" title="Flutter homepage" aria-label="Go to the Flutter homepage"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span></a></li><li role="presentation"><a href="https://docs.flutter.dev" class="site-wordmark current-site" role="menuitem" aria-current="true" title="Flutter docs homepage" aria-label="Go to the Flutter docs homepage"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span> <span class="subtype">Docs</span></a></li><li role="presentation"><a href="https://api.flutter.dev" class="site-wordmark" role="menuitem" title="Flutter API reference" aria-label="Go to the Flutter API reference"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span> <span class="subtype">API</span></a></li><li aria-hidden="true" class="dropdown-divider" role="separator"></li><li role="presentation"><a href="https://dart.dev" class="site-wordmark" role="menuitem" title="Dart homepage" aria-label="Go to the Dart homepage"><img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28"> <span>Dart</span></a></li><li role="presentation"><a href="https://dartpad.dev" class="site-wordmark" role="menuitem" title="DartPad playground" aria-label="Go to the DartPad playground"><img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28"> <span>DartPad</span></a></li><li role="presentation"><a href="https://pub.dev" class="site-wordmark" role="menuitem" title="pub.dev homepage" aria-label="Go to the pub.dev homepage"><img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28"> <span>pub.dev</span></a></li></ul></nav></div></div><div class="navbar-contents"><ul class="navbar-nav"><li class="nav-item"><a class="nav-link" href="https://flutter.dev">Homepage</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev/community">Community</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev">Packages</a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev">API reference</a></li></ul><form action="/search/" class="site-header__search"><input class="site-header__searchfield search-field" type="search" name="q" id="q" autocomplete="off" placeholder="Search" aria-label="Search"></form><a href="/search" id="fallback-search-button" class="icon-button" aria-label="Navigate to the docs search page." title="Navigate to the docs search page."><span class="material-symbols" aria-hidden="true">search</span> </a><a id="call-to-action" class="filled-button" href="/get-started/install/">Get started</a> <button id="menu-toggle" class="icon-button" type="button" aria-controls="sidenav" aria-label="Toggle navigation" title="Toggle navigation"><span class="material-symbols" aria-hidden="true">menu</span></button></div></nav></header><div id="site-below-header"><div id="site-main-row"><div id="sidenav" class="site-sidebar"><nav><ul><li class="nav-header">Get started</li><li class="nav-item"><a class="nav-link" href="/get-started/install"><div><span>Set up Flutter</span></div></a></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#sidenav-3" role="button" aria-expanded="true" aria-controls="sidenav-3"><span>Learn Flutter</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="sidenav-3"><li class="nav-item"><a class="nav-link" href="/get-started/learn-flutter"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/codelab"><div><span>Write your first app</span></div></a></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#sidenav-3-3" role="button" aria-expanded="true" aria-controls="sidenav-3-3"><span>Learn the fundamentals</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="sidenav-3-3"><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/dart"><div><span>Intro to Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/widgets"><div><span>Widgets</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/layout"><div><span>Layout</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/state-management"><div><span>State management</span></div></a></li><li class="nav-item"><a class="nav-link active" href="/get-started/fundamentals/user-input"><div><span>Handling user input</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/networking"><div><span>Networking and data</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/local-caching"><div><span>Local data and caching</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-3-4" role="button" aria-expanded="false" aria-controls="sidenav-3-4"><span>From another platform?</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-3-4"><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/android-devs"><div><span>Flutter for Android devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/compose-devs"><div><span>Flutter for Jetpack Compose devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/swiftui-devs"><div><span>Flutter for SwiftUI devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/uikit-devs"><div><span>Flutter for UIKit devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/react-native-devs"><div><span>Flutter for React Native devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/web-devs"><div><span>Flutter for web devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/xamarin-forms-devs"><div><span>Flutter for Xamarin.Forms devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/declarative"><div><span>Introduction to declarative UI</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/dart-swift-concurrency"><div><span>Flutter versus Swift concurrency</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/codelabs"><div><span>Codelabs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook"><div><span>Cookbook</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/samples" target="_blank" rel="noopener"><div><span>Demos and samples</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-4" role="button" aria-expanded="false" aria-controls="sidenav-4"><span>Stay up to date</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-4"><li class="nav-item"><a class="nav-link" href="/release/upgrade"><div><span>Upgrade</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/archive"><div><span>SDK archive</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/release/whats-new"><div><span>What's new</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/release-notes"><div><span>Release notes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes"><div><span>Breaking changes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/compatibility-policy"><div><span>Compatibility policy</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-5" role="button" aria-expanded="false" aria-controls="sidenav-5"><span>App solutions</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-1" role="button" aria-expanded="false" aria-controls="sidenav-5-1"><span>AI</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-1"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-1-1" role="button" aria-expanded="false" aria-controls="sidenav-5-1-1"><span>AI Toolkit guide</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-1-1"><li class="nav-item"><a class="nav-link" href="/ai-toolkit"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/user-experience"><div><span>User experience</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/feature-integration"><div><span>Feature integration</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/custom-llm-providers"><div><span>Custom LLM providers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/chat-client-sample"><div><span>Chat client sample</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=1AuzJEiHjO4" target="_blank" rel="noopener"><div><span>Build with Google AI Dart SDK (video)</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-2" role="button" aria-expanded="false" aria-controls="sidenav-5-2"><span>Firebase & Firestore</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter" target="_blank" rel="noopener"><div><span>Discover Firebase for Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=wUSkeTaBonA" target="_blank" rel="noopener"><div><span>Get to know Firebase for Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener"><div><span>Add a user authentication flow to a Flutter app using FirebaseUI</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-get-to-know-web" target="_blank" rel="noopener"><div><span>Get to know Firebase for web</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-3" role="button" aria-expanded="false" aria-controls="sidenav-5-3"><span>Games</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-3"><li class="nav-item"><a class="nav-link" href="/resources/games-toolkit"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/achievements-leaderboard"><div><span>Add achievements and leaderboards</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/build-leaderboards-with-firestore#0" target="_blank" rel="noopener"><div><span>Build leaderboards with Firestore</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads"><div><span>Add advertising</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/firestore-multiplayer"><div><span>Add multiplayer support</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener"><div><span>Add in-app purchases</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener"><div><span>Add user authentication</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/crashlytics/get-started?platform=flutter" target="_blank" rel="noopener"><div><span>Debug using Crashlytics</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-flame-brick-breaker" target="_blank" rel="noopener"><div><span>Intro to Flame with Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4" role="button" aria-expanded="false" aria-controls="sidenav-5-4"><span>Monetization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4-1" role="button" aria-expanded="false" aria-controls="sidenav-5-4-1"><span>Advertising</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4-1"><li class="nav-item"><a class="nav-link" href="/resources/ads-overview"><div><span>Ads overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads"><div><span>Add advertising</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-ads-in-flutter" target="_blank" rel="noopener"><div><span>Add AdMob ads to your Flutter app</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-inline-ads-in-flutter" target="_blank" rel="noopener"><div><span>Add an AdMob banner and native inline ads</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/admob/flutter/mediation" target="_blank" rel="noopener"><div><span>Google AdMob mediation</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/interactive_media_ads" target="_blank" rel="noopener"><div><span>Interactive Media Ads SDK</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4-2" role="button" aria-expanded="false" aria-controls="sidenav-5-4-2"><span>In-app purchases</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4-2"><li class="nav-item"><a class="nav-link" href="/resources/in-app-purchases-overview"><div><span>In-app purchases overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener"><div><span>Add in-app purchases</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4-3" role="button" aria-expanded="false" aria-controls="sidenav-5-4-3"><span>Payments</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4-3"><li class="nav-item"><a class="nav-link" href="/resources/payments-overview"><div><span>Payments overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/pay" target="_blank" rel="noopener"><div><span>Google pay package</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-5" role="button" aria-expanded="false" aria-controls="sidenav-5-5"><span>Maps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-5"><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/google-maps-in-flutter" target="_blank" rel="noopener"><div><span>Add Google maps to a Flutter app</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/maps/flutter-package" target="_blank" rel="noopener"><div><span>Google Maps package</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-6" role="button" aria-expanded="false" aria-controls="sidenav-5-6"><span>News</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/resources/news-toolkit"><div><span>Build a news app</span></div></a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-header">User interface</li><li class="nav-item"><a class="nav-link" href="/ui"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/widgets"><div><span>Widget catalog</span></div></a></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-10" role="button" aria-expanded="false" aria-controls="sidenav-10"><span>Layout</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-10"><li class="nav-item"><a class="nav-link" href="/ui/layout"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/tutorial"><div><span>Build a layout</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-10-3" role="button" aria-expanded="false" aria-controls="sidenav-10-3"><span>Lists & grids</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-10-3"><li class="nav-item"><a class="nav-link" href="/cookbook/lists/basic-list"><div><span>Create and use lists</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/horizontal-list"><div><span>Create a horizontal list</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/grid-lists"><div><span>Create a grid view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/mixed-list"><div><span>Create lists with different types of items</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/spaced-items"><div><span>Create lists with spaced items</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/long-lists"><div><span>Work with long lists</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-10-4" role="button" aria-expanded="false" aria-controls="sidenav-10-4"><span>Scrolling</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-10-4"><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling/slivers"><div><span>Use slivers to achieve fancy scrolling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/floating-app-bar"><div><span>Place a floating app bar above a list</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/parallax-scrolling"><div><span>Create a scrolling parallax effect</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-11" role="button" aria-expanded="false" aria-controls="sidenav-11"><span>Adaptive & responsive design</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-11"><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/general"><div><span>General approach</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/safearea-mediaquery"><div><span>SafeArea & MediaQuery</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/large-screens"><div><span>Large screens & foldables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/input"><div><span>User input & accessibility</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/capabilities"><div><span>Capabilities & policies</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/platform-adaptations"><div><span>Automatic platform adaptations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/best-practices"><div><span>Best practices</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/more-info"><div><span>Additional resources</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-12" role="button" aria-expanded="false" aria-controls="sidenav-12"><span>Design & theming</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-12"><li class="nav-item"><a class="nav-link" href="/cookbook/design/themes"><div><span>Share styles with themes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/design/material"><div><span>Material design</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes/material-3-migration"><div><span>Migrate to Material 3</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-12-4" role="button" aria-expanded="false" aria-controls="sidenav-12-4"><span>Text</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-12-4"><li class="nav-item"><a class="nav-link" href="/ui/design/text/typography"><div><span>Fonts & typography</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/fonts"><div><span>Use a custom font</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/package-fonts"><div><span>Export fonts from a package</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_fonts" target="_blank" rel="noopener"><div><span>Google Fonts package</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-12-5" role="button" aria-expanded="false" aria-controls="sidenav-12-5"><span>Custom graphics</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-12-5"><li class="nav-item"><a class="nav-link" href="/ui/design/graphics/fragment-shaders"><div><span>Use custom fragment shaders</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-13" role="button" aria-expanded="false" aria-controls="sidenav-13"><span>Interactivity</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-13"><li class="nav-item"><a class="nav-link" href="/ui/interactivity"><div><span>Add interactivity to your app</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-13-2" role="button" aria-expanded="false" aria-controls="sidenav-13-2"><span>Gestures</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-13-2"><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/handling-taps"><div><span>Handle taps</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures/drag-outside"><div><span>Drag an object outside an app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/drag-a-widget"><div><span>Drag a UI element within an app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/ripples"><div><span>Add Material touch ripples</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/dismissible"><div><span>Implement swipe to dismiss</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-13-3" role="button" aria-expanded="false" aria-controls="sidenav-13-3"><span>Input & forms</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-13-3"><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-input"><div><span>Create and style a text field</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/retrieve-input"><div><span>Retrieve the value of a text field</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-field-changes"><div><span>Handle changes to a text field</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/focus"><div><span>Manage focus in text fields</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/validation"><div><span>Build a form with validation</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/snackbars"><div><span>Display a snackbar</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/actions-and-shortcuts"><div><span>Implement actions & shortcuts</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/focus"><div><span>Manage keyboard focus</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-14" role="button" aria-expanded="false" aria-controls="sidenav-14"><span>Assets & media</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-14"><li class="nav-item"><a class="nav-link" href="/ui/assets/assets-and-images"><div><span>Add assets and images</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/network-image"><div><span>Display images from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/fading-in-images"><div><span>Fade in images with a placeholder</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/play-video"><div><span>Play and pause a video</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/assets/asset-transformation"><div><span>Transform assets at build time</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-15" role="button" aria-expanded="false" aria-controls="sidenav-15"><span>Navigation & routing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-15"><li class="nav-item"><a class="nav-link" href="/ui/navigation"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/tabs"><div><span>Add tabs to your app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/navigation-basics"><div><span>Navigate to a new screen and back</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/passing-data"><div><span>Send data to a new screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/returning-data"><div><span>Return data from a screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/drawer"><div><span>Add a drawer to a screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/deep-linking"><div><span>Set up deep linking</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-app-links"><div><span>Set up app links for Android</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-universal-links"><div><span>Set up universal links for iOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/url-strategies"><div><span>Configure web URL strategies</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-16" role="button" aria-expanded="false" aria-controls="sidenav-16"><span>Animations & transitions</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-16"><li class="nav-item"><a class="nav-link" href="/ui/animations"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/tutorial"><div><span>Tutorial</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/implicit-animations"><div><span>Implicit animations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/animated-container"><div><span>Animate the properties of a container</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/opacity-animation"><div><span>Fade a widget in and out</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/hero-animations"><div><span>Hero animations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/page-route-animation"><div><span>Animate a page route transition</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/physics-simulation"><div><span>Animate using a physics simulation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/staggered-animations"><div><span>Staggered animations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/staggered-menu-animation"><div><span>Create a staggered menu animation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/overview"><div><span>API overview</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-17" role="button" aria-expanded="false" aria-controls="sidenav-17"><span>Accessibility & internationalization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-17"><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/accessibility"><div><span>Accessibility</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/internationalization"><div><span>Internationalization</span></div></a></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-header">Beyond UI</li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-20" role="button" aria-expanded="false" aria-controls="sidenav-20"><span>Data & backend</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-1" role="button" aria-expanded="false" aria-controls="sidenav-20-1"><span>State management</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-1"><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/intro"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/declarative"><div><span>Think declaratively</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/ephemeral-vs-app"><div><span>Ephemeral vs app state</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/simple"><div><span>Simple app state management</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/options"><div><span>Options</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-2" role="button" aria-expanded="false" aria-controls="sidenav-20-2"><span>Networking & http</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/networking"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/fetch-data"><div><span>Fetch data from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/authenticated-requests"><div><span>Make authenticated requests</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/send-data"><div><span>Send data to the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/update-data"><div><span>Update data over the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/delete-data"><div><span>Delete data on the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/web-sockets"><div><span>Communicate with WebSockets</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-3" role="button" aria-expanded="false" aria-controls="sidenav-20-3"><span>Serialization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-3"><li class="nav-item"><a class="nav-link" href="/data-and-backend/serialization/json"><div><span>JSON serialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/background-parsing"><div><span>Parse JSON in the background</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-4" role="button" aria-expanded="false" aria-controls="sidenav-20-4"><span>Persistence</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-4"><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/key-value"><div><span>Store key-value data on disk</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/reading-writing-files"><div><span>Read and write files</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/sqlite"><div><span>Persist data with SQLite</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-5" role="button" aria-expanded="false" aria-controls="sidenav-20-5"><span>Firebase</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-5"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter/setup" target="_blank" rel="noopener"><div><span>Add Firebase to your Flutter app</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/google-apis"><div><span>Google APIs</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-21" role="button" aria-expanded="false" aria-controls="sidenav-21"><span>App architecture</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-21"><li class="nav-item"><a class="nav-link" href="/app-architecture"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/concepts"><div><span>Architecture concepts</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/guide"><div><span>Guide to app architecture</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-21-4" role="button" aria-expanded="false" aria-controls="sidenav-21-4"><span>Architecture case study</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-21-4"><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/ui-layer"><div><span>UI layer</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/data-layer"><div><span>Data layer</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/dependency-injection"><div><span>Dependency injection</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/testing"><div><span>Testing each layer</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/app-architecture/recommendations"><div><span>Recommendations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/design-patterns"><div><span>Design patterns</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-22" role="button" aria-expanded="false" aria-controls="sidenav-22"><span>Platform integration</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22"><li class="nav-item"><a class="nav-link" href="/reference/supported-platforms"><div><span>Supported platforms</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/desktop"><div><span>Build desktop apps with Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-channels"><div><span>Write platform-specific code</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-4" role="button" aria-expanded="false" aria-controls="sidenav-22-4"><span>Android</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-4"><li class="nav-item"><a class="nav-link" href="/platform-integration/android/install-android"><div><span>Add Android as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/splash-screen"><div><span>Add a splash screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/predictive-back"><div><span>Add predictive back</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/c-interop"><div><span>Bind to native code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/platform-views"><div><span>Host a native Android view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/call-jetpack-apis"><div><span>Calling JetPack APIs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/compose-activity"><div><span>Launch a Jetpack Compose activity</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/restore-state-android"><div><span>Restore state on Android</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/chromeos"><div><span>Target ChromeOS with Android</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-5" role="button" aria-expanded="false" aria-controls="sidenav-22-5"><span>iOS</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-5"><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/install-ios"><div><span>Add iOS as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-latest"><div><span>Flutter on latest iOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/apple-frameworks"><div><span>Leverage Apple's system libraries</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/launch-screen"><div><span>Add a launch screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-app-clip"><div><span>Add iOS App Clip support</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/app-extensions"><div><span>Add iOS app extensions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/c-interop"><div><span>Bind to native code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/platform-views"><div><span>Host a native iOS view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-debugging"><div><span>Enable debugging on iOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/restore-state-ios"><div><span>Restore state on iOS</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-6" role="button" aria-expanded="false" aria-controls="sidenav-22-6"><span>Linux</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-6"><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/install-linux"><div><span>Add Linux as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/building"><div><span>Build a Linux app</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-7" role="button" aria-expanded="false" aria-controls="sidenav-22-7"><span>macOS</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-7"><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/install-macos"><div><span>Add macOS as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/building"><div><span>Build a macOS app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/c-interop"><div><span>Bind to native code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/platform-views"><div><span>Host a native macOS view</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-8" role="button" aria-expanded="false" aria-controls="sidenav-22-8"><span>Web</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-8"><li class="nav-item"><a class="nav-link" href="/platform-integration/web"><div><span>Web support in Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/install-web"><div><span>Add web as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/building"><div><span>Build a web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/wasm"><div><span>Compile to WebAssembly</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/initialization"><div><span>Customize app initialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web"><div><span>Add Flutter to any web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-content-in-flutter"><div><span>Web content in Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/renderers"><div><span>Web renderers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-images"><div><span>Display images on the web</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/faq"><div><span>Web FAQ</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-9" role="button" aria-expanded="false" aria-controls="sidenav-22-9"><span>Windows</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-9"><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/install-windows"><div><span>Add Windows as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/building"><div><span>Build a Windows app</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-23" role="button" aria-expanded="false" aria-controls="sidenav-23"><span>Packages & plugins</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-23"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/using-packages"><div><span>Use packages & plugins</span></div></a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/developing-packages"><div><span>Develop packages & plugins</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-23-3" role="button" aria-expanded="false" aria-controls="sidenav-23-3"><span>Swift Package Manager</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-23-3"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-app-developers"><div><span>For app developers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-plugin-authors"><div><span>For plugin authors</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/favorites"><div><span>Flutter Favorites</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/flutter" target="_blank" rel="noopener"><div><span>Package repository</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-24" role="button" aria-expanded="false" aria-controls="sidenav-24"><span>Testing & debugging</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24"><li class="nav-header">Testing</li><li class="nav-item"><a class="nav-link" href="/testing/overview"><div><span>Overview</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-24-3" role="button" aria-expanded="false" aria-controls="sidenav-24-3"><span>Unit testing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24-3"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/introduction"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/mocking"><div><span>Mock dependencies</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-24-4" role="button" aria-expanded="false" aria-controls="sidenav-24-4"><span>Widget testing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24-4"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/introduction"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/finders"><div><span>Find widgets</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/scrolling"><div><span>Simulate scrolling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/tap-drag"><div><span>Simulate user interaction</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-24-5" role="button" aria-expanded="false" aria-controls="sidenav-24-5"><span>Integration testing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24-5"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/introduction"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/integration-tests"><div><span>Write and run an integration test</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/profiling"><div><span>Profile an integration test</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/testing/testing-plugins"><div><span>Test a plugin</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/plugins-in-tests"><div><span>Handle plugin code in tests</span></div></a></li><li class="nav-header">Debugging</li><li class="nav-item"><a class="nav-link" href="/testing/debugging"><div><span>Debugging tools</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/code-debugging"><div><span>Debug your app programmatically</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/native-debugging"><div><span>Use a native language debugger</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/common-errors"><div><span>Common Flutter errors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/errors"><div><span>Handle errors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/maintenance/error-reporting"><div><span>Report errors to a service</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-25" role="button" aria-expanded="false" aria-controls="sidenav-25"><span>Performance & optimization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-25"><li class="nav-item"><a class="nav-link" href="/perf"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/impeller"><div><span>Impeller</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/best-practices"><div><span>Performance best practices</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/app-size"><div><span>App size</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/deferred-components"><div><span>Deferred components</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/rendering-performance"><div><span>Rendering performance</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/ui-performance"><div><span>Performance profiling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/web-performance"><div><span>Performance profiling for web</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/metrics"><div><span>Performance metrics</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/isolates"><div><span>Concurrency and isolates</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/faq"><div><span>Performance FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/appendix"><div><span>Appendix</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-26" role="button" aria-expanded="false" aria-controls="sidenav-26"><span>Deployment</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-26"><li class="nav-item"><a class="nav-link" href="/deployment/obfuscate"><div><span>Obfuscate Dart code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors"><div><span>Create app flavors for Android</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors-ios"><div><span>Create app flavors for iOS and macOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/android"><div><span>Build and release an Android app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/ios"><div><span>Build and release an iOS app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/macos"><div><span>Build and release a macOS app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/linux"><div><span>Build and release a Linux app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/windows"><div><span>Build and release a Windows app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/web"><div><span>Build and release a web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/cd"><div><span>Set up continuous deployment</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-27" role="button" aria-expanded="false" aria-controls="sidenav-27"><span>Add to an existing app</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-27"><li class="nav-item"><a class="nav-link" href="/add-to-app"><div><span>Introduction</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-27-2" role="button" aria-expanded="false" aria-controls="sidenav-27-2"><span>Add to an Android app</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-27-2"><li class="nav-item"><a class="nav-link" href="/add-to-app/android/project-setup"><div><span>Set up Android project</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-screen"><div><span>Add a single Flutter screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-fragment"><div><span>Add a Flutter Fragment</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-view"><div><span>Add a Flutter View</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/plugin-setup"><div><span>Use a Flutter plugin</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-27-3" role="button" aria-expanded="false" aria-controls="sidenav-27-3"><span>Add to an iOS app</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-27-3"><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/project-setup"><div><span>Set up iOS project</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/add-flutter-screen"><div><span>Add a single Flutter screen</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web"><div><span>Add to a web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/debugging"><div><span>Debug embedded Flutter module</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/multiple-flutters"><div><span>Add multiple Flutter instances</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/performance"><div><span>Loading sequence and performance</span></div></a></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-29" role="button" aria-expanded="false" aria-controls="sidenav-29"><span>Tools & editors</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-29"><li class="nav-item"><a class="nav-link" href="/tools/android-studio"><div><span>Android Studio & IntelliJ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code"><div><span>Visual Studio Code</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-29-3" role="button" aria-expanded="false" aria-controls="sidenav-29-3"><span>DevTools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-29-3"><li class="nav-item"><a class="nav-link" href="/tools/devtools"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/android-studio"><div><span>Run from Android Studio & IntelliJ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/vscode"><div><span>Run from VS Code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cli"><div><span>Run from command line</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/inspector"><div><span>Flutter inspector</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/legacy-inspector"><div><span>Legacy Flutter inspector</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/performance"><div><span>Performance view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cpu-profiler"><div><span>CPU Profiler view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/memory"><div><span>Memory view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/console"><div><span>Debug console view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/network"><div><span>Network view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/debugger"><div><span>Debugger</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/logging"><div><span>Logging view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/app-size"><div><span>App size tool</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/extensions"><div><span>DevTools extensions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/deep-links"><div><span>Validate deep links</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/release-notes"><div><span>Release notes</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/sdk"><div><span>SDK overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pubspec"><div><span>Flutter's pubspec options</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/flutter-fix"><div><span>Automated fixes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/formatting"><div><span>Code formatting</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-30" role="button" aria-expanded="false" aria-controls="sidenav-30"><span>Flutter concepts</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-30"><li class="nav-item"><a class="nav-link" href="/resources/architectural-overview"><div><span>Architectural overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/inside-flutter"><div><span>Inside Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/constraints"><div><span>Understanding constraints</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes"><div><span>Flutter's build modes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/hot-reload"><div><span>Hot reload</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-31" role="button" aria-expanded="false" aria-controls="sidenav-31"><span>Resources</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-31"><li class="nav-item"><a class="nav-link" href="/resources/faq"><div><span>FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/books"><div><span>Books</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/videos"><div><span>Videos</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/courses"><div><span>Courses</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/bootstrap-into-dart"><div><span>Learn Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/support"><div><span>Get support</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-31-8" role="button" aria-expanded="false" aria-controls="sidenav-31-8"><span>Contribute</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-31-8"><li class="nav-item"><a class="nav-link" href="/resources/bug-reports"><div><span>Create useful bug reports</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener"><div><span>Contribute to Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/design-docs"><div><span>Discover proposed features</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-31-9" role="button" aria-expanded="false" aria-controls="sidenav-31-9"><span>Reference</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-31-9"><li class="nav-item"><a class="nav-link" href="/dash"><div><span>Who is Dash?</span></div></a></li><li class="nav-item"><a class="nav-link" href="/reference/widgets"><div><span>Widget index</span></div></a></li><li class="nav-item"><a class="nav-link" href="/reference/flutter-cli"><div><span>flutter CLI</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev" target="_blank" rel="noopener"><div><span>API docs</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></li></ul></nav></div><main class="site-content"><div id="site-toc--side" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item"><a class="nav-link" href="#introduction-to-handling-user-input">Introduction to handling user input</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#buttons">Buttons</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#text">Text</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#selectabletext">SelectableText</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#richtext">RichText</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#textfield">TextField</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#form">Form</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#select-a-value-from-a-group-of-options">Select a value from a group of options</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#segmentedbutton">SegmentedButton</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#chip">Chip</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#dropdownmenu">DropdownMenu</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#slider">Slider</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#toggle-between-values">Toggle between values</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#checkbox-switch-and-radio">Checkbox, Switch, and Radio</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#checkbox">Checkbox</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#switch">Switch</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#radio">Radio</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#select-a-date-or-time">Select a date or time</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#datepickerdialog">DatePickerDialog</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#timepickerdialog">TimePickerDialog</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#swipe-slide">Swipe & slide</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#dismissible">Dismissible</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#looking-for-more-widgets">Looking for more widgets?</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#build-interactive-widgets-with-gesturedetector">Build interactive widgets with GestureDetector</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#dont-forget-about-accessibility">Don't forget about accessibility!</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#testing">Testing</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#next-networking">Next: Networking</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#feedback">Feedback</a></li></ul></div><article><header class="site-content__title"><h1 id="document-title">Handling user input</h1><nav class="breadcrumbs" aria-label="breadcrumb"><ol vocab="https://schema.org/" typeof="BreadcrumbList"><li class="breadcrumb-item" property="itemListElement" typeof="ListItem"><a href="/get-started" property="item" typeof="WebPage"><span property="name">Get started</span></a><meta property="position" content="0"><span class="material-symbols child-icon" aria-hidden="true">chevron_right</span></li><li class="breadcrumb-item" property="itemListElement" typeof="ListItem"><a href="/get-started/fundamentals" property="item" typeof="WebPage"><span property="name">Fundamentals</span></a><meta property="position" content="1"><span class="material-symbols child-icon" aria-hidden="true">chevron_right</span></li><li class="breadcrumb-item active" property="itemListElement" typeof="ListItem" aria-current="page"><a href="/get-started/fundamentals/user-input" property="item" typeof="WebPage"><span property="name">Handling user input</span></a><meta property="position" content="2"></li></ol></nav></header><div id="site-toc--inline" class="site-toc toc-collapsible toc-collapsed"><header class="site-toc__title">Contents <span class="site-toc--inline__toggle toc-toggle-down" title="Expand table of contents"><i class="material-symbols" aria-hidden="true">keyboard_arrow_down</i></span> <span class="site-toc--inline__toggle toc-toggle-up" title="Collapse table of contents"><i class="material-symbols" aria-hidden="true">keyboard_arrow_up</i></span></header><ul class="section-nav"><li class="toc-entry"><a href="#introduction-to-handling-user-input">Introduction to handling user input</a></li><li class="toc-entry"><a href="#buttons">Buttons</a></li><li class="toc-entry"><a href="#text">Text</a><ul><li class="toc-entry"><a href="#selectabletext">SelectableText</a></li><li class="toc-entry"><a href="#richtext">RichText</a></li><li class="toc-entry"><a href="#textfield">TextField</a></li><li class="toc-entry"><a href="#form">Form</a></li></ul></li><li class="toc-entry"><a href="#select-a-value-from-a-group-of-options">Select a value from a group of options</a><ul><li class="toc-entry"><a href="#segmentedbutton">SegmentedButton</a></li><li class="toc-entry"><a href="#chip">Chip</a></li><li class="toc-entry"><a href="#dropdownmenu">DropdownMenu</a></li><li class="toc-entry"><a href="#slider">Slider</a></li></ul></li><li class="toc-entry"><a href="#toggle-between-values">Toggle between values</a><ul><li class="toc-entry"><a href="#checkbox-switch-and-radio">Checkbox, Switch, and Radio</a></li><li class="toc-entry"><a href="#checkbox">Checkbox</a></li><li class="toc-entry"><a href="#switch">Switch</a></li><li class="toc-entry"><a href="#radio">Radio</a></li></ul></li><li class="toc-entry"><a href="#select-a-date-or-time">Select a date or time</a><ul><li class="toc-entry"><a href="#datepickerdialog">DatePickerDialog</a></li><li class="toc-entry"><a href="#timepickerdialog">TimePickerDialog</a></li></ul></li><li class="toc-entry"><a href="#swipe-slide">Swipe & slide</a><ul><li class="toc-entry"><a href="#dismissible">Dismissible</a></li></ul></li><li class="toc-entry"><a href="#looking-for-more-widgets">Looking for more widgets?</a></li><li class="toc-entry"><a href="#build-interactive-widgets-with-gesturedetector">Build interactive widgets with GestureDetector</a><ul><li class="toc-entry"><a href="#dont-forget-about-accessibility">Don't forget about accessibility!</a></li></ul></li><li class="toc-entry"><a href="#testing">Testing</a></li><li class="toc-entry"><a href="#next-networking">Next: Networking</a></li><li class="toc-entry"><a href="#feedback">Feedback</a></li></ul><span class="site-toc--inline__toggle toc-toggle-more-items" title="Expand table of contents"><i class="material-symbols" aria-hidden="true">more_horiz</i></span></div><p>Now that you know how to manage state in your Flutter app, how can you let users interact with your app and change its state?</p><div class="header-wrapper"><h2 id="introduction-to-handling-user-input">Introduction to handling user input</h2><a class="heading-link" href="#introduction-to-handling-user-input" aria-label="Link to 'Introduction to handling user input' section">#</a></div><p>As a multi-platform UI framework, there are many different ways for users to interact with a Flutter app. The resources in this section introduce you to some of the common widgets used for enabling user interaction within your app.</p><p>Some user input mechanisms, like <a href="/get-started/fundamentals/layout#scrolling-widgets">scrolling</a>, have already been covered in <a href="/get-started/fundamentals/layout">Layouts</a>.</p><aside class="alert alert-secondary"><div class="alert-header"><span>About design system support</span></div><div class="alert-content"><p>Flutter ships with prebuilt components for two design systems as part of the SDK, <a href="/ui/widgets/material">Material</a> and <a href="/ui/widgets/cupertino">Cupertino</a>. For educational purposes, this page focuses on Material widgets, components that are stylized according to the <a href="https://m3.material.io/">Material 3 design language</a> specifications.</p><p>The Flutter community on <a href="https://pub.dev">pub.dev</a>, the package repository for Dart and Flutter, create and support additional design languages such as <a href="https://pub.dev/packages/fluent_ui">Fluent UI</a>, <a href="https://pub.dev/packages/macos_ui">macOS UI</a>, and more. If the existing design system components don't quite fit what you need, Flutter lets you build your own custom widgets, which is covered at the end of this section. No matter which design system you choose, the principals on this page apply.</p></div></aside><blockquote><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>Reference</strong>: The <a href="/ui/widgets#design-systems">widget catalog</a> has an inventory of commonly used widgets in the <a href="/ui/widgets/material">Material</a> and <a href="/ui/widgets/cupertino">Cupertino</a> libraries.</p></blockquote><p>Next, we'll cover a few of the Material widgets that support common use cases for handling user input in your Flutter app.</p><div class="header-wrapper"><h2 id="buttons">Buttons</h2><a class="heading-link" href="#buttons" aria-label="Link to 'Buttons' section">#</a></div><p><img src="/assets/images/docs/fwe/user-input/material-buttons.png" alt="A collection of Material 3 Buttons."></p><p>Buttons allow a user to initiate an action in the UI by clicking or tapping. The Material library provides a variety of button types that are functionally similar, but styled differently for various use cases, including:</p><ul><li><code>ElevatedButton</code>: A button with some depth. Use elevated buttons to add dimension to otherwise mostly flat layouts.</li><li><code>FilledButton</code>: A filled button that should be used for important, final actions that complete a flow, like <strong>Save</strong>, <strong>Join now</strong>, or <strong>Confirm</strong>.</li><li><code>Tonal Button</code>: A middle ground button between <code>FilledButton</code> and <code>OutlinedButton</code>. They're useful in contexts where a lower-priority button requires more emphasis than an outline, like <strong>Next</strong>.</li><li><code>OutlinedButton</code>: A button with text and a visible border. These buttons contain actions that are important, but aren't the primary action in an app.</li><li><code>TextButton</code>: Clickable text, without a border. Since text buttons don't have visible borders, they must rely on their position relative to other content for context.</li><li><code>IconButton</code>: A button with an icon.</li><li><code>FloatingActionButton</code>: An icon button that hovers over content to promote a primary action.</li></ul><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch/2uaoEDOgk_I?si=MQZcSp24oRaS_kiY">FloatingActionButton (Widget of the Week)</a></p></blockquote><p>There are usually 3 main aspects to constructing a button: style, callback, and its child, as seen in the following <code>ElevatedButton</code> sample code:</p><ul><li><p>A button's callback function, <code>onPressed</code>, determines what happens when the button is clicked, therefore, this function is where you update your app state. If the callback is <code>null</code>, the button is disabled and nothing happens when a user presses the button.</p></li><li><p>The button's <code>child</code>, which is displayed within the button's content area, is usually text or an icon that indicates the button's purpose.</p></li><li><p>Finally, a button's <code>style</code> controls its appearance: color, border, and so on.</p></li></ul><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">int</span><span style="color:#222222"> count = </span><span style="color:#0C7064">0</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> ElevatedButton</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> style: </span><span style="color:#0468D7">ElevatedButton</span><span style="color:#222222">.</span><span style="color:#6200EE">styleFrom</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> textStyle: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> TextStyle</span><span style="color:#222222">(fontSize: </span><span style="color:#0C7064">20</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> onPressed: () {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> count += </span><span style="color:#0C7064">1</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Enabled'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/ElevatedButton.gif" class="" alt="A GIF of an elevated button with the text "Enabled"" style=""><figcaption class="figure-caption">This figure shows an ElevatedButton with the text "Enabled" being clicked.</figcaption></div></figure><br><blockquote><p><span class="material-symbols" aria-hidden="true">star</span> <strong>Checkpoint</strong>: Complete this tutorial that teaches you how to build a "favorite" button: <a href="/ui/interactivity">Add interactivity to your Flutter app</a></p></blockquote><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs</strong>: <a href="https://api.flutter.dev/flutter/material/ElevatedButton-class.html"><code>ElevatedButton</code></a> • <a href="https://api.flutter.dev/flutter/material/FilledButton-class.html"><code>FilledButton</code></a> • <a href="https://api.flutter.dev/flutter/material/OutlinedButton-class.html"><code>OutlinedButton</code></a> • <a href="https://api.flutter.dev/flutter/material/TextButton-class.html"><code>TextButton</code></a> • <a href="https://api.flutter.dev/flutter/material/IconButton-class.html"><code>IconButton</code></a> • <a href="https://api.flutter.dev/flutter/material/FloatingActionButton-class.html"><code>FloatingActionButton</code></a></p><div class="header-wrapper"><h2 id="text">Text</h2><a class="heading-link" href="#text" aria-label="Link to 'Text' section">#</a></div><p>Several widgets support text input.</p><div class="header-wrapper"><h3 id="selectabletext"><code>SelectableText</code></h3><a class="heading-link" href="#selectabletext" aria-label="Link to 'SelectableText' section">#</a></div><p>Flutter's <code>Text</code> widget displays text on the screen, but doesn't allow users to highlight or copy the text. <code>SelectableText</code> displays a string of <em>user-selectable</em> text.</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SelectableText</span><span style="color:#222222">(</span><span style="color:#0C7064">'''</span></span> <span class="line"><span style="color:#0C7064">Two households, both alike in dignity,</span></span> <span class="line"><span style="color:#0C7064">In fair Verona, where we lay our scene,</span></span> <span class="line"><span style="color:#0C7064">From ancient grudge break to new mutiny,</span></span> <span class="line"><span style="color:#0C7064">Where civil blood makes civil hands unclean.</span></span> <span class="line"><span style="color:#0C7064">From forth the fatal loins of these two foes'''</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/SelectableText.gif" class="" alt="A GIF of a cursor highlighting two lines of text from a paragraph." style=""><figcaption class="figure-caption">This figure shows a cursor highlighting a portion of a string of text.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=ZSU3ZXOs6hc">SelectableText (Widget of the Week)</a></p></blockquote><div class="header-wrapper"><h3 id="richtext"><code>RichText</code></h3><a class="heading-link" href="#richtext" aria-label="Link to 'RichText' section">#</a></div><p><code>RichText</code> lets you display strings of rich text in your app. <code>TextSpan</code>, similar to <code>RichText</code>, allows you to display parts of text with different text styles. It's not for handling user input, but is useful if you're allowing users edit and format text.</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> RichText</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> text: </span><span style="color:#0468D7">TextSpan</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> text: </span><span style="color:#0C7064">'Hello '</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> style: </span><span style="color:#0468D7">DefaultTextStyle</span><span style="color:#222222">.</span><span style="color:#6200EE">of</span><span style="color:#222222">(context).style,</span></span> <span class="line"><span style="color:#222222"> children: </span><span style="color:#BD2314">const</span><span style="color:#222222"> <</span><span style="color:#0468D7">TextSpan</span><span style="color:#222222">>[</span></span> <span class="line"><span style="color:#0468D7"> TextSpan</span><span style="color:#222222">(text: </span><span style="color:#0C7064">'bold'</span><span style="color:#222222">, style: </span><span style="color:#0468D7">TextStyle</span><span style="color:#222222">(fontWeight: </span><span style="color:#0468D7">FontWeight</span><span style="color:#222222">.bold)),</span></span> <span class="line"><span style="color:#0468D7"> TextSpan</span><span style="color:#222222">(text: </span><span style="color:#0C7064">' world!'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/RichText.png" class="" alt="A screenshot of the text "Hello bold world!" with the word "bold" in bold font." style=""><figcaption class="figure-caption">This figure shows a string of text formatted with different text styles.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=rykDVh-QFfw">Rich Text (Widget of the Week)</a></p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">flutter</span> <strong>Demo</strong>: <a href="https://github.com/flutter/samples/tree/main/rich_text_editor">Rich Text Editor</a></p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">code</span> <strong>Code</strong>: <a href="https://github.com/flutter/samples/tree/main/simplistic_editor">Rich Text Editor code</a></p></blockquote><div class="header-wrapper"><h3 id="textfield"><code>TextField</code></h3><a class="heading-link" href="#textfield" aria-label="Link to 'TextField' section">#</a></div><p>A <code>TextField</code> lets users enter text in text box using a hardware or onscreen keyboard.</p><p><code>TextField</code>s have many different properties and configurations. A few of the highlights:</p><ul><li><code>InputDecoration</code> determines the text field's appearance, such as color and border.</li><li><code>controller</code>: A <code>TextEditingController</code> controls the text being edited. Why might you need a controller? By default, your app's users can type into the text field, but if you want to programmatically control the <code>TextField</code> and clear its value, for example, you'll need a <code>TextEditingController</code>.</li><li><code>onChanged</code>: This callback function triggers when the user changes the text field's value, such as when inserting or removing text.</li><li><code>onSubmitted</code>: This callback is triggered when the user indicates that they are done editing the text in the field; for example, by tapping the "enter" key when the text field is in focus.</li></ul><p>The class supports other configurable properties, such as <code>obscureText</code> that turns each letter into a <code>readOnly</code> circle as its entered and <code>readOnly</code> which prevents the user from changing the text.</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">final</span><span style="color:#0468D7"> TextEditingController</span><span style="color:#222222"> _controller = </span><span style="color:#0468D7">TextEditingController</span><span style="color:#222222">();</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> TextField</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> controller: _controller,</span></span> <span class="line"><span style="color:#222222"> decoration: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> InputDecoration</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> border: </span><span style="color:#0468D7">OutlineInputBorder</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> labelText: </span><span style="color:#0C7064">'Mascot Name'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/TextField.gif" class="" alt="A GIF of a text field with the label "Mascot Name", purple focus border and the phrase "Dash the hummingbird" being typed in." style=""><figcaption class="figure-caption">This figure shows text being typed into a TextField with a selected border and label.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">star</span> <strong>Checkpoint</strong>: Complete this 4-part cookbook series that walks you through how to create a text field, retrieve its value, and update your app state:</p><ol><li><a href="/cookbook/forms/text-input">Create and style a text field</a></li><li><a href="/cookbook/forms/retrieve-input">Retrieve the value of a text field</a></li><li><a href="/cookbook/forms/text-field-changes">Handle changes to a text field</a></li><li><a href="/cookbook/forms/focus">Focus and text fields</a>.</li></ol></blockquote><div class="header-wrapper"><h3 id="form">Form</h3><a class="heading-link" href="#form" aria-label="Link to 'Form' section">#</a></div><p><code>Form</code> is an optional container for grouping together multiple form field widgets, such as <code>TextField</code>.</p><p>Each individual form field should be wrapped in a <code>FormField</code> widget with the <code>Form</code> widget as a common ancestor. Convenience widgets exist that pre-wrap form field widgets in a <code>FormField</code> for you. For example, the <code>Form</code> widget version of <code>TextField</code> is <code>TextFormField</code>.</p><p>Using a <code>Form</code> provides access to a <code>FormState</code>, which lets you save, reset, and validate each <code>FormField</code> that descends from this <code>Form</code>. You can also provide a <code>GlobalKey</code> to identify a specific form, as shown in the following code:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">final</span><span style="color:#0468D7"> GlobalKey</span><span style="color:#222222"><</span><span style="color:#0468D7">FormState</span><span style="color:#222222">> _formKey = </span><span style="color:#0468D7">GlobalKey</span><span style="color:#222222"><</span><span style="color:#0468D7">FormState</span><span style="color:#222222">>();</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Form</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> key: _formKey,</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Column</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> crossAxisAlignment: </span><span style="color:#0468D7">CrossAxisAlignment</span><span style="color:#222222">.start,</span></span> <span class="line"><span style="color:#222222"> children: <</span><span style="color:#0468D7">Widget</span><span style="color:#222222">>[</span></span> <span class="line"><span style="color:#0468D7"> TextFormField</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> decoration: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> InputDecoration</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> hintText: </span><span style="color:#0C7064">'Enter your email'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> validator: (</span><span style="color:#0468D7">String</span><span style="color:#222222">? value) {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (value == </span><span style="color:#0C7064">null</span><span style="color:#222222"> || value.isEmpty) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0C7064"> 'Please enter some text'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0C7064"> null</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> Padding</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> padding: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> EdgeInsets</span><span style="color:#222222">.</span><span style="color:#6200EE">symmetric</span><span style="color:#222222">(vertical: </span><span style="color:#0C7064">16.0</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">ElevatedButton</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onPressed: () {</span></span> <span class="line"><span style="color:#6E6E70"> // Validate returns true if the form is valid, or false otherwise.</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (_formKey.currentState!.</span><span style="color:#6200EE">validate</span><span style="color:#222222">()) {</span></span> <span class="line"><span style="color:#6E6E70"> // Process data.</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Submit'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><blockquote><p><span class="material-symbols" aria-hidden="true">star</span> <strong>Checkpoint</strong>: Complete this tutorial to learn how to <a href="/cookbook/forms/validation">build a form with validation</a>.</p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">flutter</span> <strong>Demo</strong>: <a href="https://github.com/flutter/samples/tree/main/form_app/">Form app</a></p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">code</span> <strong>Code</strong>: <a href="https://github.com/flutter/samples/tree/main/form_app">Form app code</a></p></blockquote><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs</strong>: <a href="https://api.flutter.dev/flutter/material/TextField-class.html"><code>TextField</code></a> • <a href="https://api.flutter.dev/flutter/widgets/RichText-class.html"><code>RichText</code></a> • <a href="https://api.flutter.dev/flutter/material/SelectableText-class.html"><code>SelectableText</code></a> • <a href="https://api.flutter.dev/flutter/widgets/Form-class.html"><code>Form</code></a></p><div class="header-wrapper"><h2 id="select-a-value-from-a-group-of-options">Select a value from a group of options</h2><a class="heading-link" href="#select-a-value-from-a-group-of-options" aria-label="Link to 'Select a value from a group of options' section">#</a></div><p>Provide a way to users to select from several options.</p><div class="header-wrapper"><h3 id="segmentedbutton">SegmentedButton</h3><a class="heading-link" href="#segmentedbutton" aria-label="Link to 'SegmentedButton' section">#</a></div><p><code>SegmentedButton</code> allows users to select from a minimal group of 2-5 items.</p><p>The data type, <code><T></code>, can be a built-in type such as <code>int</code>, <code>String</code>, <code>bool</code> or an enum. A <code>SegmentedButton</code> has a few relevant properties:</p><ul><li><p><code>segments</code>, a list of <code>ButtonSegment</code>s, where each represents a "segment" or option that the user can select. Visually, each <code>ButtonSegment</code> can have an icon, text label, or both.</p></li><li><p><code>multiSelectionEnabled</code> indicates whether the user is allowed to select multiple options. This property defaults to false.</p></li><li><p><code>selected</code> identifies the currently selected value(s). <strong>Note:</strong> <code>selected</code> is of type of <code>Set<T></code>, so if you're only allowing users to select one value, that value must be provided as a<code>Set</code> with a single element.</p></li><li><p>The <code>onSelectionChanged</code> callback triggers when a user selects any segments. It provides a list of the selected segments so you can update your app state.</p></li><li><p>Additional styling parameters allow you to modify the button's appearance. For example, <code>style</code> takes a <code>ButtonStyle</code>, providing a way to configure a <code>selectedIcon</code>.</p></li></ul><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">enum</span><span style="color:#0468D7"> Calendar</span><span style="color:#222222"> { day, week, month, year }</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70">// StatefulWidget...</span></span> <span class="line"><span style="color:#0468D7">Calendar</span><span style="color:#222222"> calendarView = </span><span style="color:#0468D7">Calendar</span><span style="color:#222222">.day;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> SegmentedButton</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> segments: </span><span style="color:#BD2314">const</span><span style="color:#222222"> <</span><span style="color:#0468D7">ButtonSegment</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>>[</span></span> <span class="line"><span style="color:#0468D7"> ButtonSegment</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Calendar</span><span style="color:#222222">.day,</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Day'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> icon: </span><span style="color:#0468D7">Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.calendar_view_day)),</span></span> <span class="line"><span style="color:#0468D7"> ButtonSegment</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Calendar</span><span style="color:#222222">.week,</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Week'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> icon: </span><span style="color:#0468D7">Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.calendar_view_week)),</span></span> <span class="line"><span style="color:#0468D7"> ButtonSegment</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Calendar</span><span style="color:#222222">.month,</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Month'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> icon: </span><span style="color:#0468D7">Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.calendar_view_month)),</span></span> <span class="line"><span style="color:#0468D7"> ButtonSegment</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Calendar</span><span style="color:#222222">.year,</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Year'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> icon: </span><span style="color:#0468D7">Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.calendar_today)),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> selected: <</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">>{calendarView},</span></span> <span class="line"><span style="color:#222222"> onSelectionChanged: (</span><span style="color:#0468D7">Set</span><span style="color:#222222"><</span><span style="color:#0468D7">Calendar</span><span style="color:#222222">> newSelection) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#0468D7"> Suggested</span><span style="color:#222222"> change</span></span> <span class="line"><span style="color:#6E6E70"> // By default there is only a single segment that can be</span></span> <span class="line"><span style="color:#6E6E70"> // selected at one time, so its value is always the first</span></span> <span class="line"><span style="color:#6E6E70"> // By default, only a single segment can be</span></span> <span class="line"><span style="color:#6E6E70"> // selected at one time, so its value is always the first</span></span> <span class="line"><span style="color:#222222"> calendarView = newSelection.first;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/segmented-button.gif" class="" alt="A GIF of a SegmentedButton with 4 segments: Day, Week, Month, and Year. Each has a calendar icon to represent its value and a text label. Day is first selected, then week and month, then year." style=""><figcaption class="figure-caption">This figure shows a SegmentedButton, each segment with an icon and text representing its value.</figcaption></div></figure><div class="header-wrapper"><h3 id="chip">Chip</h3><a class="heading-link" href="#chip" aria-label="Link to 'Chip' section">#</a></div><p><code>Chip</code> is a compact way of representing an attribute, text, entity, or action for a specific context. Specialized <code>Chip</code> widgets exist for specific use cases:</p><ul><li><a href="https://api.flutter.dev/flutter/material/InputChip-class.html">InputChip</a> represents a complex piece of information, such as an entity (person, place, or thing), or conversational text, in a compact form.</li><li><a href="https://api.flutter.dev/flutter/material/ChoiceChip-class.html">ChoiceChip</a> allows a single selection from a set of options. Choice chips contain related descriptive text or categories.</li><li><a href="https://api.flutter.dev/flutter/material/FilterChip-class.html">FilterChip</a> uses tags or descriptive words to filter content.</li><li><a href="https://api.flutter.dev/flutter/material/ActionChip-class.html">ActionChip</a> represents an action related to primary content.</li></ul><p>Every <code>Chip</code> widget requires a <code>label</code>. It can optionally have an <code>avatar</code> (such as an icon or a user's profile picture) and an <code>onDeleted</code> callback, which shows a delete icon that when triggered, deletes the chip. A <code>Chip</code> widget's appearance can also be customized by setting a number of optional parameters such as <code>shape</code>, <code>color</code>, and <code>iconTheme</code>.</p><p>You will typically use <code>Wrap</code>, a widget that displays its children in multiple horizontal or vertical runs, to make sure your chips wrap and don't get cut off at the edge of your app.</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SizedBox</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> width: </span><span style="color:#0C7064">500</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Wrap</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> alignment: </span><span style="color:#0468D7">WrapAlignment</span><span style="color:#222222">.center,</span></span> <span class="line"><span style="color:#222222"> spacing: </span><span style="color:#0C7064">8</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> runSpacing: </span><span style="color:#0C7064">4</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> children: [</span></span> <span class="line"><span style="color:#0468D7"> Chip</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> avatar: </span><span style="color:#0468D7">CircleAvatar</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> backgroundImage: </span><span style="color:#0468D7">AssetImage</span><span style="color:#222222">(</span><span style="color:#0C7064">'assets/images/dash_chef.png'</span><span style="color:#222222">)),</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Chef Dash'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> Chip</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> avatar: </span><span style="color:#0468D7">CircleAvatar</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> backgroundImage:</span></span> <span class="line"><span style="color:#0468D7"> AssetImage</span><span style="color:#222222">(</span><span style="color:#0C7064">'assets/images/dash_firefighter.png'</span><span style="color:#222222">)),</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Firefighter Dash'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> Chip</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> avatar: </span><span style="color:#0468D7">CircleAvatar</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> backgroundImage: </span><span style="color:#0468D7">AssetImage</span><span style="color:#222222">(</span><span style="color:#0C7064">'assets/images/dash_musician.png'</span><span style="color:#222222">)),</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Musician Dash'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> Chip</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> avatar: </span><span style="color:#0468D7">CircleAvatar</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> backgroundImage: </span><span style="color:#0468D7">AssetImage</span><span style="color:#222222">(</span><span style="color:#0C7064">'assets/images/dash_artist.png'</span><span style="color:#222222">)),</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Artist Dash'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/chip.png" class="" alt="A screenshot of 4 Chips split over two rows with a leading circular profile image with content text." style=""><figcaption class="figure-caption">This figure shows two rows of Chip widgets, each containing a circular leading profile image and content text.</figcaption></div></figure><div class="header-wrapper"><h3 id="dropdownmenu"><code>DropdownMenu</code></h3><a class="heading-link" href="#dropdownmenu" aria-label="Link to 'DropdownMenu' section">#</a></div><p>A <code>DropdownMenu</code> allows users to select a choice from a menu of options and places the selected text into a <code>TextField</code>. It also allows users to filter the menu items based on the text input.</p><p>Configuration parameters include the following:</p><ul><li><code>dropdownMenuEntries</code> provides a list of <code>DropdownMenuEntry</code>s that describes each menu item. The menu might contain information such as a text label, and a leading or trailing icon. (This is also the only required parameter.)</li><li><code>TextEditingController</code> allows programmatically controlling the <code>TextField</code>.</li><li>The <code>onSelected</code> callback triggers when the user selects an option.</li><li><code>initialSelection</code> allows you to configure the default value.</li><li>Additional parameters are also available for customizing the widget's look and behavior.</li></ul><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">enum</span><span style="color:#0468D7"> ColorLabel</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6200EE"> blue</span><span style="color:#222222">(</span><span style="color:#0C7064">'Blue'</span><span style="color:#222222">, </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.blue),</span></span> <span class="line"><span style="color:#6200EE"> pink</span><span style="color:#222222">(</span><span style="color:#0C7064">'Pink'</span><span style="color:#222222">, </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.pink),</span></span> <span class="line"><span style="color:#6200EE"> green</span><span style="color:#222222">(</span><span style="color:#0C7064">'Green'</span><span style="color:#222222">, </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.green),</span></span> <span class="line"><span style="color:#6200EE"> yellow</span><span style="color:#222222">(</span><span style="color:#0C7064">'Orange'</span><span style="color:#222222">, </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.orange),</span></span> <span class="line"><span style="color:#6200EE"> grey</span><span style="color:#222222">(</span><span style="color:#0C7064">'Grey'</span><span style="color:#222222">, </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.grey);</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> ColorLabel</span><span style="color:#222222">(</span><span style="color:#BD2314">this</span><span style="color:#222222">.label, </span><span style="color:#BD2314">this</span><span style="color:#222222">.color);</span></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#0468D7"> String</span><span style="color:#222222"> label;</span></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#0468D7"> Color</span><span style="color:#222222"> color;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70">// StatefulWidget...</span></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> DropdownMenu</span><span style="color:#222222"><</span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> initialSelection: </span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222">.green,</span></span> <span class="line"><span style="color:#222222"> controller: colorController,</span></span> <span class="line"><span style="color:#6E6E70"> // requestFocusOnTap is enabled/disabled by platforms when it is null.</span></span> <span class="line"><span style="color:#6E6E70"> // On mobile platforms, this is false by default. Setting this to true will</span></span> <span class="line"><span style="color:#6E6E70"> // trigger focus request on the text field and virtual keyboard will appear</span></span> <span class="line"><span style="color:#6E6E70"> // afterward. On desktop platforms however, this defaults to true.</span></span> <span class="line"><span style="color:#222222"> requestFocusOnTap: </span><span style="color:#0C7064">true</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Color'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> onSelected: (</span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222">? color) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> selectedColor = color;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> dropdownMenuEntries: </span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222">.values</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">map</span><span style="color:#222222"><</span><span style="color:#0468D7">DropdownMenuEntry</span><span style="color:#222222"><</span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222">>>(</span></span> <span class="line"><span style="color:#222222"> (</span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222"> color) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> DropdownMenuEntry</span><span style="color:#222222"><</span><span style="color:#0468D7">ColorLabel</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: color,</span></span> <span class="line"><span style="color:#222222"> label: color.label,</span></span> <span class="line"><span style="color:#222222"> enabled: color.label != </span><span style="color:#0C7064">'Grey'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> style: </span><span style="color:#0468D7">MenuItemButton</span><span style="color:#222222">.</span><span style="color:#6200EE">styleFrom</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> foregroundColor: color.color,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }).</span><span style="color:#6200EE">toList</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/dropdownmenu.gif" class="" alt="A GIF the DropdownMenu widget that is selected, it displays 5 options: Blue, Pink, Green, Orange, and Grey. The option text is displayed in the color of its value." style=""><figcaption class="figure-caption">This figure shows a DropdownMenu widget with 5 value options. Each option's text color is styled to represent the color value.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=giV9AbM2gd8?si=E23hjg72cjMTe_mz">DropdownMenu (Widget of the Week)</a></p></blockquote><div class="header-wrapper"><h3 id="slider">Slider</h3><a class="heading-link" href="#slider" aria-label="Link to 'Slider' section">#</a></div><p>The <code>Slider</code> widget lets a user adjust a value by moving an indicator, such as a volume bar.</p><p>Configuration parameters for the <code>Slider</code> widget:</p><ul><li><code>value</code> represents the slider's current value</li><li><code>onChanged</code> is the callback that gets triggered when the handle is moved</li><li><code>min</code> and <code>max</code> establish minimum and maximum values allowed by the slider</li><li><code>divisions</code> establishes a discrete interval with which the user can move the handle along the track.</li></ul><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">double</span><span style="color:#222222"> _currentVolume = </span><span style="color:#0C7064">1</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Slider</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> value: _currentVolume,</span></span> <span class="line"><span style="color:#222222"> max: </span><span style="color:#0C7064">5</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> divisions: </span><span style="color:#0C7064">5</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> label: _currentVolume.</span><span style="color:#6200EE">toString</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> onChanged: (</span><span style="color:#0468D7">double</span><span style="color:#222222"> value) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> _currentVolume = value;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/slider.gif" class="" alt="A GIF of a slider that has the dial dragged left to right in increments of 1, from 0.0 to 5.0" style=""><figcaption class="figure-caption">This figure shows a slider widget with a value ranging from 0.0 to 5.0 broken up into 5 divisions. It shows the current value as a label as the dial is dragged.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=ufb4gIPDmEss">Slider, RangeSlider, CupertinoSlider (Widget of the Week)</a></p></blockquote><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs:</strong> <a href="https://api.flutter.dev/flutter/material/SegmentedButton-class.html"><code>SegmentedButton</code></a> • <a href="https://api.flutter.dev/flutter/material/DropdownMenu-class.html"><code>DropdownMenu</code></a> • <a href="https://api.flutter.dev/flutter/material/Slider-class.html"><code>Slider</code></a> • <a href="https://api.flutter.dev/flutter/material/Chip-class.html"><code>Chip</code></a></p><div class="header-wrapper"><h2 id="toggle-between-values">Toggle between values</h2><a class="heading-link" href="#toggle-between-values" aria-label="Link to 'Toggle between values' section">#</a></div><p>There are several ways that your UI can allow toggling between values.</p><div class="header-wrapper"><h3 id="checkbox-switch-and-radio">Checkbox, Switch, and Radio</h3><a class="heading-link" href="#checkbox-switch-and-radio" aria-label="Link to 'Checkbox, Switch, and Radio' section">#</a></div><p>Provide an option to toggle a single value on and off. The functional logic behind these widgets are the same, as all 3 are built on top of <code>ToggleableStateMixin</code>, though each provides slight presentation differences.:</p><ul><li><code>Checkbox</code> is a container that is empty when false or filled with a checkmark when true.</li><li><code>Switch</code> has a handle that is on the left when false and slides to the right when true.</li><li><code>Radio</code> is similar to a <code>Checkbox</code> in that it's a container that is empty when false, but filled in when true.</li></ul><p>The configuration for <code>Checkbox</code> and <code>Switch</code> contain:</p><ul><li>a <code>value</code> that is <code>true</code> or <code>false</code></li><li>and an <code>onChanged</code> callback which is triggered when the user toggles the widget</li></ul><div class="header-wrapper"><h3 id="checkbox">Checkbox</h3><a class="heading-link" href="#checkbox" aria-label="Link to 'Checkbox' section">#</a></div><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">bool</span><span style="color:#222222"> isChecked = </span><span style="color:#0C7064">false</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Checkbox</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> checkColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.white,</span></span> <span class="line"><span style="color:#222222"> value: isChecked,</span></span> <span class="line"><span style="color:#222222"> onChanged: (</span><span style="color:#0468D7">bool</span><span style="color:#222222">? value) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> isChecked = value!;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/checkbox.gif" class="" alt="A GIF that shows a pointer clicking a checkbox and then clicking again to uncheck it." style=""><figcaption class="figure-caption">This figure shows a checkbox being checked and unchecked.</figcaption></div></figure><div class="header-wrapper"><h3 id="switch">Switch</h3><a class="heading-link" href="#switch" aria-label="Link to 'Switch' section">#</a></div><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">bool</span><span style="color:#222222"> light = </span><span style="color:#0C7064">true</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Switch</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#6E6E70"> // This bool value toggles the switch.</span></span> <span class="line"><span style="color:#222222"> value: light,</span></span> <span class="line"><span style="color:#222222"> activeColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.red,</span></span> <span class="line"><span style="color:#222222"> onChanged: (</span><span style="color:#0468D7">bool</span><span style="color:#222222"> value) {</span></span> <span class="line"><span style="color:#6E6E70"> // This is called when the user toggles the switch.</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> light = value;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/Switch.gif" class="" alt="A GIF of a Switch widget that is toggled on and off. In its off state, it is gray with dark gray borders. In its on state, it is red with a light red border." style=""><figcaption class="figure-caption">This figure shows a Switch widget that is toggled on and off.</figcaption></div></figure><div class="header-wrapper"><h3 id="radio">Radio</h3><a class="heading-link" href="#radio" aria-label="Link to 'Radio' section">#</a></div><p>A group of <code>Radio</code> buttons that allows the user to select between mutually exclusive values. When the user selects a radio button in a group, the other radio buttons are unselected.</p><ul><li>A particular <code>Radio</code> button's <code>value</code> represent that button's value,</li><li>The selected value for a group of radio buttons is identified by the <code>groupValue</code> parameter.</li><li><code>Radio</code> also has an <code>onChanged</code> callback that gets triggered when users click it, like <code>Switch</code> and <code>Checkbox</code></li></ul><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">enum</span><span style="color:#0468D7"> Character</span><span style="color:#222222"> { musician, chef, firefighter, artist }</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> RadioExample</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatefulWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> RadioExample</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#0468D7"> State</span><span style="color:#222222"><</span><span style="color:#0468D7">RadioExample</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_RadioExampleState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> _RadioExampleState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222"><</span><span style="color:#0468D7">RadioExample</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> Character</span><span style="color:#222222">? _character = </span><span style="color:#0468D7">Character</span><span style="color:#222222">.musician;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> setCharacter</span><span style="color:#222222">(</span><span style="color:#0468D7">Character</span><span style="color:#222222">? value) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> _character = value;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Column</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> children: <</span><span style="color:#0468D7">Widget</span><span style="color:#222222">>[</span></span> <span class="line"><span style="color:#0468D7"> ListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Musician'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> leading: </span><span style="color:#0468D7">Radio</span><span style="color:#222222"><</span><span style="color:#0468D7">Character</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Character</span><span style="color:#222222">.musician,</span></span> <span class="line"><span style="color:#222222"> groupValue: _character,</span></span> <span class="line"><span style="color:#222222"> onChanged: setCharacter,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> ListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Chef'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> leading: </span><span style="color:#0468D7">Radio</span><span style="color:#222222"><</span><span style="color:#0468D7">Character</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Character</span><span style="color:#222222">.chef,</span></span> <span class="line"><span style="color:#222222"> groupValue: _character,</span></span> <span class="line"><span style="color:#222222"> onChanged: setCharacter,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> ListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Firefighter'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> leading: </span><span style="color:#0468D7">Radio</span><span style="color:#222222"><</span><span style="color:#0468D7">Character</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Character</span><span style="color:#222222">.firefighter,</span></span> <span class="line"><span style="color:#222222"> groupValue: _character,</span></span> <span class="line"><span style="color:#222222"> onChanged: setCharacter,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> ListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Artist'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> leading: </span><span style="color:#0468D7">Radio</span><span style="color:#222222"><</span><span style="color:#0468D7">Character</span><span style="color:#222222">>(</span></span> <span class="line"><span style="color:#222222"> value: </span><span style="color:#0468D7">Character</span><span style="color:#222222">.artist,</span></span> <span class="line"><span style="color:#222222"> groupValue: _character,</span></span> <span class="line"><span style="color:#222222"> onChanged: setCharacter,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/Radio.gif" class="" alt="A GIF of 4 ListTiles in a column, each containing a leading Radio button and title text. The Radio buttons are selected in order from top to bottom." style=""><figcaption class="figure-caption">This figure shows a column of ListTiles containing a radio button and label, where only one radio button can be selected at a time.</figcaption></div></figure><div class="header-wrapper"><h4 id="bonus-checkboxlisttile-switchlisttile">Bonus: CheckboxListTile & SwitchListTile</h4><a class="heading-link" href="#bonus-checkboxlisttile-switchlisttile" aria-label="Link to 'Bonus: CheckboxListTile & SwitchListTile' section">#</a></div><p>These convenience widgets are the same checkbox and switch widgets, but support a label (as a <code>ListTile</code>).</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">double</span><span style="color:#222222"> timeDilation = </span><span style="color:#0C7064">1.0</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#0468D7">bool</span><span style="color:#222222"> _lights = </span><span style="color:#0C7064">false</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Column</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> children: [</span></span> <span class="line"><span style="color:#0468D7"> CheckboxListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Animate Slowly'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> value: timeDilation != </span><span style="color:#0C7064">1.0</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> onChanged: (</span><span style="color:#0468D7">bool</span><span style="color:#222222">? value) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> timeDilation = value! ? </span><span style="color:#0C7064">10.0</span><span style="color:#222222"> : </span><span style="color:#0C7064">1.0</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> secondary: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.hourglass_empty),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> SwitchListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Lights'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> value: _lights,</span></span> <span class="line"><span style="color:#222222"> onChanged: (</span><span style="color:#0468D7">bool</span><span style="color:#222222"> value) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> _lights = value;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> secondary: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.lightbulb_outline),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/SpecialListTiles.gif" class="" alt="A ListTile with a leading icon, title text, and a trailing checkbox being checked and unchecked. It also shows a ListTile with a leading icon, title text and a switch being toggled on and off." style=""><figcaption class="figure-caption">This figure shows a column containing a CheckboxListTile and a SwitchListTile being toggled.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=RkSqPAn9szs">CheckboxListTile (Widget of the Week)</a></p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=0igIjvtEWNU">SwitchListTile (Widget of the Week)</a></p></blockquote><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs</strong>: <a href="https://api.flutter.dev/flutter/material/Checkbox-class.html"><code>Checkbox</code></a> • <a href="https://api.flutter.dev/flutter/material/CheckboxListTile-class.html"><code>CheckboxListTile</code></a> • <a href="https://api.flutter.dev/flutter/material/Switch-class.html"><code>Switch</code></a> • <a href="https://api.flutter.dev/flutter/material/SwitchListTile-class.html"><code>SwitchListTile</code></a> • <a href="https://api.flutter.dev/flutter/material/Radio-class.html"><code>Radio</code></a></p><div class="header-wrapper"><h2 id="select-a-date-or-time">Select a date or time</h2><a class="heading-link" href="#select-a-date-or-time" aria-label="Link to 'Select a date or time' section">#</a></div><p>Widgets are provided so the user can select a date and time.</p><p>There is a set of dialogs that enable users to select a date or time, as you'll see in the following sections. With the exception of differing date types - <code>DateTime</code> for dates vs <code>TimeOfDay</code> for time - these dialogs function similarly, you can configure them by providing:</p><ul><li>a default <code>initialDate</code> or <code>initialTime</code></li><li>or an <code>initialEntryMode</code> that determines the picker UI that's displayed.</li></ul><div class="header-wrapper"><h3 id="datepickerdialog">DatePickerDialog</h3><a class="heading-link" href="#datepickerdialog" aria-label="Link to 'DatePickerDialog' section">#</a></div><p>This dialog allows the user to select a date or a range of dates. Activate by calling the <code>showDatePicker</code> function, which returns a <code>Future<DateTime></code>, so don't forget to await the asynchronous function call!</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">DateTime</span><span style="color:#222222">? selectedDate;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> var</span><span style="color:#222222"> date = selectedDate;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Column</span><span style="color:#222222">(children: [</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> date == </span><span style="color:#0C7064">null</span></span> <span class="line"><span style="color:#222222"> ? </span><span style="color:#0C7064">"You haven't picked a date yet."</span></span> <span class="line"><span style="color:#222222"> : </span><span style="color:#0468D7">DateFormat</span><span style="color:#222222">(</span><span style="color:#0C7064">'MM-dd-yyyy'</span><span style="color:#222222">).</span><span style="color:#6200EE">format</span><span style="color:#222222">(date),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> ElevatedButton</span><span style="color:#222222">.</span><span style="color:#6200EE">icon</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> icon: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.calendar_today),</span></span> <span class="line"><span style="color:#222222"> onPressed: () </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> var</span><span style="color:#222222"> pickedDate = </span><span style="color:#BD2314">await</span><span style="color:#6200EE"> showDatePicker</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> context: context,</span></span> <span class="line"><span style="color:#222222"> initialEntryMode: </span><span style="color:#0468D7">DatePickerEntryMode</span><span style="color:#222222">.calendarOnly,</span></span> <span class="line"><span style="color:#222222"> initialDate: </span><span style="color:#0468D7">DateTime</span><span style="color:#222222">.</span><span style="color:#6200EE">now</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> firstDate: </span><span style="color:#0468D7">DateTime</span><span style="color:#222222">(</span><span style="color:#0C7064">2019</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> lastDate: </span><span style="color:#0468D7">DateTime</span><span style="color:#222222">(</span><span style="color:#0C7064">2050</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> selectedDate = pickedDate;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Pick a date'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> )</span></span> <span class="line"><span style="color:#222222"> ]);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/DatePicker.gif" class="" alt="A GIF of a pointer clicking a button that says "Pick a date", then shows a date picker. The date Friday, August 30 is selected and the "OK" button is clicked." style=""><figcaption class="figure-caption">This figure shows a DatePicker that is displayed when the "Pick a date" button is clicked.</figcaption></div></figure><div class="header-wrapper"><h3 id="timepickerdialog">TimePickerDialog</h3><a class="heading-link" href="#timepickerdialog" aria-label="Link to 'TimePickerDialog' section">#</a></div><p><code>TimePickerDialog</code> is a dialog that presents a time picker. It can be activated by calling the <code>showTimePicker()</code> function. Instead of returning a <code>Future<DateTime></code>, <code>showTimePicker</code> instead returns a <code>Future<TimeOfDay></code>. Once again, don't forget to await the function call!</p><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">TimeOfDay</span><span style="color:#222222">? selectedTime;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> var</span><span style="color:#222222"> time = selectedTime;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Column</span><span style="color:#222222">(children: [</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> time == </span><span style="color:#0C7064">null</span><span style="color:#222222"> ? </span><span style="color:#0C7064">"You haven't picked a time yet."</span><span style="color:#222222"> : time.</span><span style="color:#6200EE">format</span><span style="color:#222222">(context),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#0468D7"> ElevatedButton</span><span style="color:#222222">.</span><span style="color:#6200EE">icon</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> icon: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.calendar_today),</span></span> <span class="line"><span style="color:#222222"> onPressed: () </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> var</span><span style="color:#222222"> pickedTime = </span><span style="color:#BD2314">await</span><span style="color:#6200EE"> showTimePicker</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> context: context,</span></span> <span class="line"><span style="color:#222222"> initialEntryMode: </span><span style="color:#0468D7">TimePickerEntryMode</span><span style="color:#222222">.dial,</span></span> <span class="line"><span style="color:#222222"> initialTime: </span><span style="color:#0468D7">TimeOfDay</span><span style="color:#222222">.</span><span style="color:#6200EE">now</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> selectedTime = pickedTime;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> label: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Pick a date'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> )</span></span> <span class="line"><span style="color:#222222"> ]);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/TimePicker.gif" class="" alt="A GIF of a pointer clicking a button that says "Pick a time", then shows a time picker. The time picker shows a circular clock as the cursor moves the hour hand, then minute hand, selects PM, then the "OK" button is clicked." style=""><figcaption class="figure-caption">This figure shows a TimePicker that is displayed when the "Pick a time" button is clicked.</figcaption></div></figure><aside class="alert alert-success"><div class="alert-header"><i class="material-symbols" aria-hidden="true">lightbulb</i> <span>Tip</span></div><div class="alert-content"><p>Calling <code>showDatePicker()</code> and <code>showTimePicker()</code> is equivalent to calling <code>showDialog()</code> with <code>DatePickerDialog()</code> and <code>TimePickerDialog()</code>, respectively. Internally, both functions use the <code>showDialog()</code> function with their respective <code>Dialog</code> widgets. To enable state restoration, you can also push <code>DatePickerDialog()</code> and <code>TimePickerDialog()</code> directly on to the <code>Navigator</code> stack.</p></div></aside><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs:</strong> <a href="https://api.flutter.dev/flutter/material/showDatePicker.html"><code>showDatePicker</code></a> • <a href="https://api.flutter.dev/flutter/material/showTimePicker.html"><code>showTimePicker</code></a></p><div class="header-wrapper"><h2 id="swipe-slide">Swipe & slide</h2><a class="heading-link" href="#swipe-slide" aria-label="Link to 'Swipe & slide' section">#</a></div><div class="header-wrapper"><h3 id="dismissible"><a href="https://api.flutter.dev/flutter/widgets/Dismissible-class.html"><code>Dismissible</code></a></h3><a class="heading-link" href="#dismissible" aria-label="Link to 'Dismissible' section">#</a></div><p>A <code>Dismissible</code> is a widget that enables users to dismiss it by swiping. It has a number of configuration parameters, including:</p><ul><li>A <code>child</code> widget</li><li>An <code>onDismissed</code> callback that is triggered when the user swipes</li><li>Styling parameters such as <code>background</code></li><li>It's important to include a <code>key</code> object as well so that they can be uniquely identified from sibling <code>Dismissible</code> widgets in the widget tree.</li></ul><figure class="code-and-image"><div class=""><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">List</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">> items = </span><span style="color:#0468D7">List</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">>.</span><span style="color:#6200EE">generate</span><span style="color:#222222">(</span><span style="color:#0C7064">100</span><span style="color:#222222">, (</span><span style="color:#0468D7">int</span><span style="color:#222222"> index) => index);</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">@override</span></span> <span class="line"><span style="color:#0468D7">Widget</span><span style="color:#6200EE"> build</span><span style="color:#222222">(</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> ListView</span><span style="color:#222222">.</span><span style="color:#6200EE">builder</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> itemCount: items.length,</span></span> <span class="line"><span style="color:#222222"> padding: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> EdgeInsets</span><span style="color:#222222">.</span><span style="color:#6200EE">symmetric</span><span style="color:#222222">(vertical: </span><span style="color:#0C7064">16</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> itemBuilder: (</span><span style="color:#0468D7">BuildContext</span><span style="color:#222222"> context, </span><span style="color:#0468D7">int</span><span style="color:#222222"> index) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> Dismissible</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> background: </span><span style="color:#0468D7">Container</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> color: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.green,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> key: </span><span style="color:#0468D7">ValueKey</span><span style="color:#222222"><</span><span style="color:#0468D7">int</span><span style="color:#222222">>(items[index]),</span></span> <span class="line"><span style="color:#222222"> onDismissed: (</span><span style="color:#0468D7">DismissDirection</span><span style="color:#222222"> direction) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> items.</span><span style="color:#6200EE">removeAt</span><span style="color:#222222">(index);</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">ListTile</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#0C7064"> 'Item </span><span style="color:#0C7064">${</span><span style="color:#222222">items</span><span style="color:#0C7064">[</span><span style="color:#222222">index</span><span style="color:#0C7064">]}</span><span style="color:#0C7064">'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> },</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></div><div><img src="/assets/images/docs/fwe/user-input/Dismissible.gif" class="" alt="A screenshot of three widgets, spaced evenly from each other." style=""><figcaption class="figure-caption">This figure shows a list of Dismissible widgets that each contain a ListTile. Swiping across the ListTile reveals a green background makes the tile disappear.</figcaption></div></figure><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=iEMgjrfuc58?si=f0S7IdaA9PIWIYvl">Dismissible (Widget of the Week)</a></p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">star</span> <strong>Checkpoint</strong>: Complete this tutorial on how to <a href="/cookbook/gestures/dismissible">implement swipe to dismiss</a> using the dismissible widget.</p></blockquote><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs:</strong> <a href="https://api.flutter.dev/flutter/widgets/Dismissible-class.html"><code>Dismissible</code></a></p><div class="header-wrapper"><h2 id="looking-for-more-widgets">Looking for more widgets?</h2><a class="heading-link" href="#looking-for-more-widgets" aria-label="Link to 'Looking for more widgets?' section">#</a></div><p>This page features just a few of the common Material widgets that you can use for handling user input in your Flutter app. Check out the <a href="/ui/widgets/material">Material Widget library</a> and <a href="https://api.flutter.dev/flutter/material/material-library.html">Material Library API docs</a> for a full list of widgets.</p><blockquote><p><span class="material-symbols" aria-hidden="true">flutter</span> <strong>Demo</strong>: See Flutter's <a href="https://github.com/flutter/samples/tree/main/material_3_demo">Material 3 Demo</a> for a curated sample of user input widgets available in the Material library.</p></blockquote><p>If the Material and Cupertino libraries don't have a widget that does what you need, check out <a href="https://pub.dev">pub.dev</a> to find Flutter & Dart community-owned and maintained packages. For example, the <a href="https://pub.dev/packages/flutter_slidable"><code>flutter_slidable</code></a> package provides a <code>Slidable</code> widget that is more customizable than the <code>Dismissible</code> widget described in the previous section.</p><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=QFcFEpFmNJ8">flutter_slidable (Package of the Week)</a></p></blockquote><div class="header-wrapper"><h2 id="build-interactive-widgets-with-gesturedetector">Build interactive widgets with GestureDetector</h2><a class="heading-link" href="#build-interactive-widgets-with-gesturedetector" aria-label="Link to 'Build interactive widgets with GestureDetector' section">#</a></div><p>Have you scoured the widget libraries, pub.dev, asked your coding friends, and still can't find a widget that fits the user interaction that you're looking for? You can build your own custom widget and make it interactive using <code>GestureDetector</code>.</p><blockquote><p><span class="material-symbols" aria-hidden="true">star</span> <strong>Checkpoint</strong>: Use this recipe as a starting point to create your own <em>custom</em> button widget that can <a href="/cookbook/gestures/handling-taps">handle taps</a>.</p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=WhVXkCFPmK4">GestureDetector (Widget of the Week)</a></p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>Reference</strong>: Check out <a href="/ui/interactivity/gestures#gestures">Taps, drags, and other gestures</a> which explains how to listen for, and respond to, gestures in Flutter.</p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Bonus Video</strong>: Curious how Flutter's <code>GestureArena</code> turns raw user interaction data into human recognizable concepts like taps, drags, and pinches? Check out this video: <a href="https://youtube.com/watch?v=Q85LBtBdi0U">GestureArena (Decoding Flutter)</a></p></blockquote><div class="header-wrapper"><h3 id="dont-forget-about-accessibility">Don't forget about accessibility!</h3><a class="heading-link" href="#dont-forget-about-accessibility" aria-label="Link to 'Don't forget about accessibility!' section">#</a></div><p>If you're building a custom widget, annotate its meaning with the <code>Semantics</code> widget. It provides descriptions and metadata to screen readers and other semantic analysis-based tools.</p><blockquote><p><span class="material-symbols" aria-hidden="true">slideshow</span> <strong>Video</strong>: <a href="https://youtube.com/watch?v=NvtMt_DtFrQ?si=o79BqAg9NAl8EE8_">Semantics (Flutter Widget of the Week)</a></p></blockquote><br><p><span class="material-symbols" aria-hidden="true">menu_book</span> <strong>API Docs</strong>: <a href="https://api.flutter.dev/flutter/widgets/GestureDetector-class.html"><code>GestureDetector</code></a> • <a href="https://api.flutter.dev/flutter/widgets/Semantics-class.html"><code>Semantics</code></a></p><div class="header-wrapper"><h2 id="testing">Testing</h2><a class="heading-link" href="#testing" aria-label="Link to 'Testing' section">#</a></div><p>Once you have finished building user interactions into your app, don't forget to write tests to ensure that everything works as expected!</p><p>These tutorials walk you through writing tests that simulate user interactions in your app:</p><blockquote><p><span class="material-symbols" aria-hidden="true">star</span> <strong>Checkpoint</strong>: Follow this <a href="/cookbook/testing/widget/tap-drag">tap, drag, and enter text</a> cookbook article and learn how to use <code>WidgetTester</code> to simulate and test user interactions in your app.</p></blockquote><blockquote><p><span class="material-symbols" aria-hidden="true">bookmark</span> <strong>Bonus Tutorial</strong>: The <a href="/cookbook/testing/widget/scrolling">handle scrolling</a> cookbook recipe shows you how to verify that lists of widgets contain the expected content by scrolling through the lists using widget tests.</p></blockquote><div class="header-wrapper"><h2 id="next-networking">Next: Networking</h2><a class="heading-link" href="#next-networking" aria-label="Link to 'Next: Networking' section">#</a></div><p>This page was an introduction to handling user input. Now that you know how to handle input from app users, you can make your app even more interesting by adding external data. In the next section, you'll learn now to fetch data for your app over a network, how to convert data to and from JSON, authentication, and other networking features.</p><div class="header-wrapper"><h2 id="feedback">Feedback</h2><a class="heading-link" href="#feedback" aria-label="Link to 'Feedback' section">#</a></div><p>As this section of the website is evolving, we <a href="https://google.qualtrics.com/jfe/form/SV_6A9KxXR7XmMrNsy?page=%22user-input%22">welcome your feedback</a>!</p><nav class="site-nextprev-nav"><ul><li class="prev"><a href="/get-started/fundamentals/state-management">State management</a></li><li class="next"><a href="/get-started/fundamentals/networking">Networking and data</a></li></ul></nav><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects the latest stable version of Flutter. Page last updated on 2025-02-10.</span> <a href="https://github.com/flutter/website/tree/main/src/content/get-started/fundamentals/user-input.md" target="_blank" rel="noopener">View source</a> <span>or </span><a href="https://github.com/flutter/website/issues/new?template=1_page_issue.yml&&page-url=https://docs.flutter.dev/get-started/fundamentals/user-input/&page-source=https://github.com/flutter/website/tree/main/src/content/get-started/fundamentals/user-input.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></article></main></div><footer id="site-footer"><div class="footer-section footer-main"><a class="brand" href="https://flutter.dev"><img src="/assets/images/branding/flutter/logo+text/horizontal/white.svg" alt="Flutter logo" width="164"></a><div class="footer-social-links"><a class="icon-button" href="https://medium.com/flutter" target="_blank" rel="noopener" title="Flutter's Medium blog"><svg><use href="/assets/images/social/medium.svg#medium"></use></svg> </a><a class="icon-button" href="https://youtube.com/@flutterdev" target="_blank" rel="noopener" title="Flutter's YouTube"><svg><use href="/assets/images/social/youtube.svg#youtube"></use></svg> </a><a class="icon-button" href="https://github.com/flutter" target="_blank" rel="noopener" title="Flutter's GitHub"><svg><use href="/assets/images/social/github.svg#github"></use></svg> </a><a class="icon-button" href="https://bsky.app/profile/flutter.dev" target="_blank" rel="noopener" title="Flutter's Bluesky"><svg><use href="/assets/images/social/bluesky.svg#bluesky"></use></svg> </a><a class="icon-button" href="https://twitter.com/FlutterDev" target="_blank" rel="noopener" title="Flutter's X (Twitter)"><svg><use href="/assets/images/social/x.svg#x"></use></svg></a></div></div><div class="footer-section footer-tray"><div class="footer-licenses">Except as otherwise noted, this site is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</a>.</div><div class="footer-utility-links"><ul><li><a href="/tos" title="Terms of use">Terms</a></li><li><a href="/brand" title="Brand usage guidelines">Brand</a></li><li><a href="https://policies.google.com/privacy" target="_blank" rel="noopener" title="Privacy policy">Privacy</a></li><li><a href="/security" title="Security philosophy and practices">Security</a></li></ul></div></div></footer></div><script src="/assets/js/tabs.js?v=4"></script><script src="/assets/js/archive.js?v=4"></script><script src="/assets/js/main.js?v=4"></script></body></html>