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"></head><body><a href="#site-content-title" id="skip">Skip to main content</a><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="btn btn-primary">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="overlay-under-drawer"></div><header class="site-header"><nav class="navbar navbar-expand-md justify-content-start justify-content-md-between"><button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><i class="material-symbols">menu</i></button> <a class="navbar-brand" href="/"><img src="/assets/images/branding/flutter/logo+text/horizontal/default.svg" alt="Flutter logo" height="37" width="129" class="align-middle"></a><div id="navbarSupportedContent" class="collapse navbar-collapse flex-grow-0"><div class="site-header__sheet-bg" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"></div><div class="site-header__sheet"><ul class="navbar-nav"><div class="site-sidebar site-sidebar--header d-md-none"><ul class="nav flex-column"><li class="nav-header">Get started</li><li class="nav-item"><a class="nav-link" href="/get-started/install">Set up Flutter</a></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" href="#header-sidenav-3" role="button" aria-expanded="true" aria-controls="header-sidenav-3">Learn Flutter</a><ul class="nav flex-column flex-nowrap collapse show" id="header-sidenav-3"><li class="nav-item"><a class="nav-link" href="/get-started/learn-flutter">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/codelab">Write your first app</a></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" data-target="#header-sidenav-3-3" href="#header-sidenav-3-3" role="button" aria-expanded="true" aria-controls="header-sidenav-3-3">Learn the fundamentals</a><ul class="nav flex-column flex-nowrap collapse show" id="header-sidenav-3-3"><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/dart">Intro to Dart</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/widgets">Widgets</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/layout">Layout</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/state-management">State management</a></li><li class="nav-item"><a class="nav-link active" href="/get-started/fundamentals/user-input">Handling user input</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/networking">Networking and data</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/local-caching">Local data and caching</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-3-4" href="/get-started/flutter-for" role="button" aria-expanded="false" aria-controls="header-sidenav-3-4">From another platform?</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-3-4"><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/android-devs">Flutter for Android devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/swiftui-devs">Flutter for SwiftUI devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/uikit-devs">Flutter for UIKit devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/react-native-devs">Flutter for React Native devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/web-devs">Flutter for web devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/xamarin-forms-devs">Flutter for Xamarin.Forms devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/declarative">Introduction to declarative UI</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/dart-swift-concurrency">Flutter versus Swift concurrency</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/codelabs">Codelabs</a></li><li class="nav-item"><a class="nav-link" href="/cookbook">Cookbook</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.github.io/samples/" target="_blank" rel="noopener">Demos and samples</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-4" role="button" aria-expanded="false" aria-controls="header-sidenav-4">Stay up to date</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-4"><li class="nav-item"><a class="nav-link" href="/release/upgrade">Upgrade</a></li><li class="nav-item"><a class="nav-link" href="/release/archive">SDK archive</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/release/whats-new">What's new</a></li><li class="nav-item"><a class="nav-link" href="/release/release-notes">Release notes</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes">Breaking changes</a></li><li class="nav-item"><a class="nav-link" href="/release/compatibility-policy">Compatibility policy</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-5" role="button" aria-expanded="false" aria-controls="header-sidenav-5">App solutions</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-1" href="#header-sidenav-5-1" role="button" aria-expanded="false" aria-controls="header-sidenav-5-1">AI</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-1"><li class="nav-item"><a class="nav-link" href="/resources/ai-overview">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://ai.google.dev/gemini-api/docs/get-started/dart" target="_blank" rel="noopener">Get started with the Gemini API</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_generative_ai" target="_blank" rel="noopener">Google AI Dart SDK (pub.dev)</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=1AuzJEiHjO4" target="_blank" rel="noopener">Build with Google AI Dart SDK (video)</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-2" href="#header-sidenav-5-2" role="button" aria-expanded="false" aria-controls="header-sidenav-5-2">Firebase & Firestore</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter" target="_blank" rel="noopener">Discover Firebase for Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=wUSkeTaBonA" target="_blank" rel="noopener">Get to know Firebase for Flutter</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">Add a user authentication flow to a Flutter app using FirebaseUI</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">Get to know Firebase for web</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-3" href="#header-sidenav-5-3" role="button" aria-expanded="false" aria-controls="header-sidenav-5-3">Games</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-3"><li class="nav-item"><a class="nav-link" href="/resources/games-toolkit">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/achievements-leaderboard">Add achievements and leaderboards</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">Build leaderboards with Firestore</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/firestore-multiplayer">Add multiplayer support</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">Add in-app purchases</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">Add user authentication</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">Debug using Crashlytics</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">Intro to Flame with Flutter</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4" href="#header-sidenav-5-4" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4">Monetization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4-1" href="#header-sidenav-5-4-1" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4-1">Advertising</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4-1"><li class="nav-item"><a class="nav-link" href="/resources/ads-overview">Ads overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</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">Add AdMob ads to your Flutter app</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">Add an AdMob banner and native inline ads</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/admob/flutter/mediation" target="_blank" rel="noopener">Google AdMob mediation</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/interactive_media_ads" target="_blank" rel="noopener">Interactive Media Ads SDK</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4-2" href="#header-sidenav-5-4-2" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4-2">In-app purchases</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4-2"><li class="nav-item"><a class="nav-link" href="/resources/in-app-purchases-overview">In-app purchases overview</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">Add in-app purchases</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-4-3" href="#header-sidenav-5-4-3" role="button" aria-expanded="false" aria-controls="header-sidenav-5-4-3">Payments</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-4-3"><li class="nav-item"><a class="nav-link" href="/resources/payments-overview">Payments overview</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/pay" target="_blank" rel="noopener">Google pay package</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-5" href="#header-sidenav-5-5" role="button" aria-expanded="false" aria-controls="header-sidenav-5-5">Maps</a><ul class="nav flex-column flex-nowrap collapse" id="header-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">Add Google maps to a Flutter app</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/maps/flutter-package" target="_blank" rel="noopener">Google Maps package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-5-6" href="#header-sidenav-5-6" role="button" aria-expanded="false" aria-controls="header-sidenav-5-6">News</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/resources/news-toolkit">Build a news app</a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">User interface</li><li class="nav-item"><a class="nav-link" href="/ui">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/widgets">Widget catalog</a></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-10" role="button" aria-expanded="false" aria-controls="header-sidenav-10">Layout</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-10"><li class="nav-item"><a class="nav-link" href="/ui/layout">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/tutorial">Build a layout</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-10-3" href="/ui/layout/lists" role="button" aria-expanded="false" aria-controls="header-sidenav-10-3">Lists & grids</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-10-3"><li class="nav-item"><a class="nav-link" href="/cookbook/lists/basic-list">Create and use lists</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/horizontal-list">Create a horizontal list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/grid-lists">Create a grid view</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/mixed-list">Create lists with different types of items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/spaced-items">Create lists with spaced items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/long-lists">Work with long lists</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-10-4" href="/ui/layout/scrolling" role="button" aria-expanded="false" aria-controls="header-sidenav-10-4">Scrolling</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-10-4"><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling/slivers">Use slivers to achieve fancy scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/floating-app-bar">Place a floating app bar above a list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/parallax-scrolling">Create a scrolling parallax effect</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-11" role="button" aria-expanded="false" aria-controls="header-sidenav-11">Adaptive & responsive design</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-11"><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/general">General approach</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/safearea-mediaquery">SafeArea & MediaQuery</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/large-screens">Large screens & foldables</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/input">User input & accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/capabilities">Capabilities & policies</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/best-practices">Best practices</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/more-info">Additional resources</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-12" role="button" aria-expanded="false" aria-controls="header-sidenav-12">Design & theming</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-12"><li class="nav-item"><a class="nav-link" href="/cookbook/design/themes">Share styles with themes</a></li><li class="nav-item"><a class="nav-link" href="/ui/design/material">Material design</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes/material-3-migration">Migrate to Material 3</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-12-4" href="/ui/design/text" role="button" aria-expanded="false" aria-controls="header-sidenav-12-4">Text</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-12-4"><li class="nav-item"><a class="nav-link" href="/ui/design/text/typography">Fonts & typography</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/fonts">Use a custom font</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/package-fonts">Export fonts from a package</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_fonts" target="_blank" rel="noopener">Google Fonts package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-12-5" href="/ui/design/graphics" role="button" aria-expanded="false" aria-controls="header-sidenav-12-5">Custom graphics</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-12-5"><li class="nav-item"><a class="nav-link" href="/ui/design/graphics/fragment-shaders">Use custom fragment shaders</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-13" role="button" aria-expanded="false" aria-controls="header-sidenav-13">Interactivity</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-13"><li class="nav-item"><a class="nav-link" href="/ui/interactivity">Add interactivity to your app</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-13-2" href="/ui/interactivity/gestures" role="button" aria-expanded="false" aria-controls="header-sidenav-13-2">Gestures</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-13-2"><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/handling-taps">Handle taps</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures/drag-outside">Drag an object outside an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/drag-a-widget">Drag a UI element within an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/ripples">Add Material touch ripples</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/dismissible">Implement swipe to dismiss</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-13-3" href="/ui/interactivity/input" role="button" aria-expanded="false" aria-controls="header-sidenav-13-3">Input & forms</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-13-3"><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-input">Create and style a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/retrieve-input">Retrieve the value of a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-field-changes">Handle changes to a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/focus">Manage focus in text fields</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/validation">Build a form with validation</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/snackbars">Display a snackbar</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/actions-and-shortcuts">Implement actions & shortcuts</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/focus">Manage keyboard focus</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-14" role="button" aria-expanded="false" aria-controls="header-sidenav-14">Assets & media</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-14"><li class="nav-item"><a class="nav-link" href="/ui/assets/assets-and-images">Add assets and images</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/network-image">Display images from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/fading-in-images">Fade in images with a placeholder</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/play-video">Play and pause a video</a></li><li class="nav-item"><a class="nav-link" href="/ui/assets/asset-transformation">Transform assets at build time</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-15" role="button" aria-expanded="false" aria-controls="header-sidenav-15">Navigation & routing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-15"><li class="nav-item"><a class="nav-link" href="/ui/navigation">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/tabs">Add tabs to your app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/navigation-basics">Navigate to a new screen and back</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/passing-data">Send data to a new screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/returning-data">Return data from a screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/drawer">Add a drawer to a screen</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/deep-linking">Set up deep linking</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-app-links">Set up app links for Android</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-universal-links">Set up universal links for iOS</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/url-strategies">Configure web URL strategies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-16" role="button" aria-expanded="false" aria-controls="header-sidenav-16">Animations & transitions</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-16"><li class="nav-item"><a class="nav-link" href="/ui/animations">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/tutorial">Tutorial</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/implicit-animations">Implicit animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/animated-container">Animate the properties of a container</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/opacity-animation">Fade a widget in and out</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/hero-animations">Hero animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/page-route-animation">Animate a page route transition</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/physics-simulation">Animate using a physics simulation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/staggered-animations">Staggered animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/staggered-menu-animation">Create a staggered menu animation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/overview">API overview</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-17" role="button" aria-expanded="false" aria-controls="header-sidenav-17">Accessibility & internationalization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-17"><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/accessibility">Accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/internationalization">Internationalization</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">Beyond UI</li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-20" role="button" aria-expanded="false" aria-controls="header-sidenav-20">Data & backend</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-1" href="/data-and-backend/state-mgmt" role="button" aria-expanded="false" aria-controls="header-sidenav-20-1">State management</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-1"><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/intro">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/declarative">Think declaratively</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/ephemeral-vs-app">Ephemeral vs app state</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/simple">Simple app state management</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/options">Options</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-2" href="/data-and-backend/networking" role="button" aria-expanded="false" aria-controls="header-sidenav-20-2">Networking & http</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/networking">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/fetch-data">Fetch data from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/authenticated-requests">Make authenticated requests</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/send-data">Send data to the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/update-data">Update data over the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/delete-data">Delete data on the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/web-sockets">Communicate with WebSockets</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-3" href="/data-and-backend/serialization" role="button" aria-expanded="false" aria-controls="header-sidenav-20-3">Serialization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-3"><li class="nav-item"><a class="nav-link" href="/data-and-backend/serialization/json">JSON serialization</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/background-parsing">Parse JSON in the background</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-4" href="/data-and-backend/persistence" role="button" aria-expanded="false" aria-controls="header-sidenav-20-4">Persistence</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-4"><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/key-value">Store key-value data on disk</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/reading-writing-files">Read and write files</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/sqlite">Persist data with SQLite</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-20-5" href="/data-and-backend/firebase" role="button" aria-expanded="false" aria-controls="header-sidenav-20-5">Firebase</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-20-5"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter/setup" target="_blank" rel="noopener">Add Firebase to your Flutter app</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/google-apis">Google APIs</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-21" role="button" aria-expanded="false" aria-controls="header-sidenav-21">App architecture</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-21"><li class="nav-item"><a class="nav-link" href="/app-architecture">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/concepts">Architecture concepts</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/guide">Guide to app architecture</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/recommendations">Recommendations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-21-5" href="/cookbook/architecture" role="button" aria-expanded="false" aria-controls="header-sidenav-21-5">Design patterns</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-21-5"><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/optimistic-state">Optimistic state</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/key-value-data">Persistent storage architecture: Key-value data</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/sql">Persistent storage architecture: SQL</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/offline-first">Offline-first</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-22" role="button" aria-expanded="false" aria-controls="header-sidenav-22">Platform integration</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22"><li class="nav-item"><a class="nav-link" href="/reference/supported-platforms">Supported platforms</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/desktop">Build desktop apps with Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-channels">Write platform-specific code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-adaptations">Automatic platform adaptations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-5" href="/platform-integration/android" role="button" aria-expanded="false" aria-controls="header-sidenav-22-5">Android</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-5"><li class="nav-item"><a class="nav-link" href="/platform-integration/android/install-android">Add Android as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/splash-screen">Add a splash screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/predictive-back">Add predictive back</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/platform-views">Host a native Android view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/compose-activity">Launch a Jetpack Compose activity</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/restore-state-android">Restore state on Android</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/chromeos">Target ChromeOS with Android</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-6" href="/platform-integration/ios" role="button" aria-expanded="false" aria-controls="header-sidenav-22-6">iOS</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-6"><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/install-ios">Add iOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-latest">Flutter on latest iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/apple-frameworks">Leverage Apple's system libraries</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/launch-screen">Add a launch screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-app-clip">Add iOS App Clip support</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/app-extensions">Add iOS app extensions</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/platform-views">Host a native iOS view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-debugging">Enable debugging on iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/restore-state-ios">Restore state on iOS</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-7" href="/platform-integration/linux" role="button" aria-expanded="false" aria-controls="header-sidenav-22-7">Linux</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-7"><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/install-linux">Add Linux as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/building">Build a Linux app</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-8" href="/platform-integration/macos" role="button" aria-expanded="false" aria-controls="header-sidenav-22-8">macOS</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-8"><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/install-macos">Add macOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/building">Build a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/platform-views">Host a native macOS view</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-9" href="/platform-integration/web" role="button" aria-expanded="false" aria-controls="header-sidenav-22-9">Web</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-9"><li class="nav-item"><a class="nav-link" href="/platform-integration/web/">Web support in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/install-web">Add web as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/building">Build a web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/wasm">Compile to WebAssembly</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/initialization">Customize app initialization</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add Flutter to any web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-content-in-flutter">Web content in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/renderers">Web renderers</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-images">Display images on the web</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/faq">Web FAQ</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-22-10" href="/platform-integration/windows" role="button" aria-expanded="false" aria-controls="header-sidenav-22-10">Windows</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-22-10"><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/install-windows">Add Windows as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/building">Build a Windows app</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-23" role="button" aria-expanded="false" aria-controls="header-sidenav-23">Packages & plugins</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-23"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/using-packages">Use packages & plugins</a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/developing-packages">Develop packages & plugins</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-23-3" href="/packages-and-plugins/swift-package-manager" role="button" aria-expanded="false" aria-controls="header-sidenav-23-3">Swift Package Manager</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-23-3"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-app-developers">For app developers</a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-plugin-authors">For plugin authors</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/favorites">Flutter Favorites</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/flutter" target="_blank" rel="noopener">Package repository</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-24" role="button" aria-expanded="false" aria-controls="header-sidenav-24">Testing & debugging</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24"><li class="nav-header">Testing</li><li class="nav-item"><a class="nav-link" href="/testing/overview">Overview</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-24-3" href="#header-sidenav-24-3" role="button" aria-expanded="false" aria-controls="header-sidenav-24-3">Unit testing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24-3"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/mocking">Mock dependencies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-24-4" href="#header-sidenav-24-4" role="button" aria-expanded="false" aria-controls="header-sidenav-24-4">Widget testing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24-4"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/finders">Find widgets</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/scrolling">Simulate scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/tap-drag">Simulate user interaction</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-24-5" href="#header-sidenav-24-5" role="button" aria-expanded="false" aria-controls="header-sidenav-24-5">Integration testing</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-24-5"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/testing/integration-tests">Write and run an integration test</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/profiling">Profile an integration test</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/testing/testing-plugins">Test a plugin</a></li><li class="nav-item"><a class="nav-link" href="/testing/plugins-in-tests">Handle plugin code in tests</a></li><li class="nav-header">Debugging</li><li class="nav-item"><a class="nav-link" href="/testing/debugging">Debugging tools</a></li><li class="nav-item"><a class="nav-link" href="/testing/code-debugging">Debug your app programmatically</a></li><li class="nav-item"><a class="nav-link" href="/testing/native-debugging">Use a native language debugger</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/testing/common-errors">Common Flutter errors</a></li><li class="nav-item"><a class="nav-link" href="/testing/errors">Handle errors</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/maintenance/error-reporting">Report errors to a service</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-25" role="button" aria-expanded="false" aria-controls="header-sidenav-25">Performance & optimization</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-25"><li class="nav-item"><a class="nav-link" href="/perf">Overview</a></li><li class="nav-item"><a class="nav-link" href="/perf/impeller">Impeller</a></li><li class="nav-item"><a class="nav-link" href="/perf/best-practices">Performance best practices</a></li><li class="nav-item"><a class="nav-link" href="/perf/app-size">App size</a></li><li class="nav-item"><a class="nav-link" href="/perf/deferred-components">Deferred components</a></li><li class="nav-item"><a class="nav-link" href="/perf/rendering-performance">Rendering performance</a></li><li class="nav-item"><a class="nav-link" href="/perf/ui-performance">Performance profiling</a></li><li class="nav-item"><a class="nav-link" href="/perf/web-performance">Performance profiling for web</a></li><li class="nav-item"><a class="nav-link" href="/perf/shader">Shader compilation jank</a></li><li class="nav-item"><a class="nav-link" href="/perf/metrics">Performance metrics</a></li><li class="nav-item"><a class="nav-link" href="/perf/isolates">Concurrency and isolates</a></li><li class="nav-item"><a class="nav-link" href="/perf/faq">Performance FAQ</a></li><li class="nav-item"><a class="nav-link" href="/perf/appendix">Appendix</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-26" role="button" aria-expanded="false" aria-controls="header-sidenav-26">Deployment</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-26"><li class="nav-item"><a class="nav-link" href="/deployment/obfuscate">Obfuscate Dart code</a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors">Create flavors of an app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/android">Build and release an Android app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/ios">Build and release an iOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/macos">Build and release a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/linux">Build and release a Linux app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/windows">Build and release a Windows app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/web">Build and release a web app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/cd">Set up continuous deployment</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-27" role="button" aria-expanded="false" aria-controls="header-sidenav-27">Add to an existing app</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-27"><li class="nav-item"><a class="nav-link" href="/add-to-app">Introduction</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-27-2" href="/add-to-app/android" role="button" aria-expanded="false" aria-controls="header-sidenav-27-2">Add to an Android app</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-27-2"><li class="nav-item"><a class="nav-link" href="/add-to-app/android/project-setup">Set up Android project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-screen">Add a single Flutter screen</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-fragment">Add a Flutter Fragment</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-view">Add a Flutter View</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/plugin-setup">Use a Flutter plugin</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-27-3" href="/add-to-app/ios" role="button" aria-expanded="false" aria-controls="header-sidenav-27-3">Add to an iOS app</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-27-3"><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/project-setup">Set up iOS project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/add-flutter-screen">Add a single Flutter screen</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add to a web app</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/debugging">Debug embedded Flutter module</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/multiple-flutters">Add multiple Flutter instances</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/performance">Loading sequence and performance</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-29" role="button" aria-expanded="false" aria-controls="header-sidenav-29">Tools & editors</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-29"><li class="nav-item"><a class="nav-link" href="/tools/android-studio">Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code">Visual Studio Code</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-29-3" href="/tools/devtools" role="button" aria-expanded="false" aria-controls="header-sidenav-29-3">DevTools</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-29-3"><li class="nav-item"><a class="nav-link" href="/tools/devtools">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/android-studio">Run from Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/vscode">Run from VS Code</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cli">Run from command line</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/inspector">Flutter inspector</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/performance">Performance view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cpu-profiler">CPU Profiler view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/memory">Memory view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/console">Debug console view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/network">Network view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/debugger">Debugger</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/logging">Logging view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/app-size">App size tool</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/extensions">DevTools extensions</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/deep-links">Validate deep links</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/release-notes">Release notes</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/sdk">SDK overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/pubspec">Flutter's pubspec options</a></li><li class="nav-item"><a class="nav-link" href="/tools/flutter-fix">Automated fixes</a></li><li class="nav-item"><a class="nav-link" href="/tools/formatting">Code formatting</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-30" role="button" aria-expanded="false" aria-controls="header-sidenav-30">Flutter concepts</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-30"><li class="nav-item"><a class="nav-link" href="/resources/architectural-overview">Architectural overview</a></li><li class="nav-item"><a class="nav-link" href="/resources/inside-flutter">Inside Flutter</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/constraints">Understanding constraints</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/tools/hot-reload">Hot reload</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#header-sidenav-31" role="button" aria-expanded="false" aria-controls="header-sidenav-31">Resources</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-31"><li class="nav-item"><a class="nav-link" href="/resources/faq">FAQ</a></li><li class="nav-item"><a class="nav-link" href="/resources/books">Books</a></li><li class="nav-item"><a class="nav-link" href="/resources/videos">Videos</a></li><li class="nav-item"><a class="nav-link" href="/resources/courses">Courses</a></li><li class="nav-item"><a class="nav-link" href="/resources/bootstrap-into-dart">Learn Dart</a></li><li class="nav-item"><a class="nav-link" href="/resources/support">Get support</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-31-8" href="#header-sidenav-31-8" role="button" aria-expanded="false" aria-controls="header-sidenav-31-8">Contribute</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-31-8"><li class="nav-item"><a class="nav-link" href="/resources/bug-reports">Create useful bug reports</a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener">Contribute to Flutter</a></li><li class="nav-item"><a class="nav-link" href="/resources/design-docs">Discover proposed features</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#header-sidenav-31-9" href="/reference" role="button" aria-expanded="false" aria-controls="header-sidenav-31-9">Reference</a><ul class="nav flex-column flex-nowrap collapse" id="header-sidenav-31-9"><li class="nav-item"><a class="nav-link" href="/dash">Who is Dash?</a></li><li class="nav-item"><a class="nav-link" href="/reference/widgets">Widget index</a></li><li class="nav-item"><a class="nav-link" href="/reference/flutter-cli">flutter CLI</a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev" target="_blank" rel="noopener">API docs</a></li></ul></li></ul></li></ul></div><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="platform-navbar-dropdown" href="https://flutter.dev/multi-platform" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Multi-Platform</a><div class="dropdown-menu" aria-labelledby="platform-navbar-dropdown"><a class="dropdown-item" href="https://flutter.dev/multi-platform/mobile">Mobile</a> <a class="dropdown-item" href="https://flutter.dev/multi-platform/web">Web</a> <a class="dropdown-item" href="https://flutter.dev/multi-platform/desktop">Desktop</a> <a class="dropdown-item" href="https://flutter.dev/multi-platform/embedded">Embedded</a></div></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="dev-navbar-dropdown" href="https://flutter.dev/" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Development</a><div class="dropdown-menu" aria-labelledby="dev-navbar-dropdown"><a class="dropdown-item" href="https://flutter.dev/learn">Learn</a> <a class="dropdown-item" href="https://pub.dev/flutter/favorites" target="_blank">Flutter Favorites</a> <a class="dropdown-item" href="https://pub.dev/" target="_blank">Packages</a> <a class="dropdown-item" href="https://flutter.dev/monetization">Monetization</a> <a class="dropdown-item" href="https://flutter.dev/games">Games</a> <a class="dropdown-item" href="https://flutter.dev/news">News</a></div></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" id="ecosystem-navbar-dropdown" href="https://flutter.dev/ecosystem" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Ecosystem</a><div class="dropdown-menu" aria-labelledby="ecosystem-navbar-dropdown"><a class="dropdown-item" href="https://flutter.dev/community">Community</a> <a class="dropdown-item" href="https://flutter.dev/events">Events</a> <a class="dropdown-item" href="https://flutter.dev/culture">Culture</a></div></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev/showcase">Showcase</a></li><li class="nav-item dropdown docs-item"><a class="nav-link dropdown-toggle" id="docs-navbar-dropdown" href="/" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Docs</a><div class="dropdown-menu" aria-labelledby="docs-navbar-dropdown"><a class="dropdown-item" href="/release/whats-new">What's new</a> <a class="dropdown-item" href="/get-started/editor">Editor support</a> <a class="dropdown-item" href="/tools/hot-reload">Hot reload</a> <a class="dropdown-item" href="/perf/ui-performance">Profiling</a> <a class="dropdown-item" href="/get-started/install">Install Flutter</a> <a class="dropdown-item" href="/tools/devtools">DevTools</a> <a class="dropdown-item" href="/cookbook">Cookbook</a> <a class="dropdown-item" href="/codelabs">Codelabs</a></div></li></ul><form action="/search/" class="site-header__search form-inline"><input class="site-header__searchfield form-control search-field" type="search" name="q" id="q" autocomplete="off" placeholder="Search" aria-label="Search"></form></div></div><div class="site-header__social navbar-nav flex-row"><a class="nav-item nav-link nav-icon" href="https://twitter.com/FlutterDev" aria-label="Open Flutter's X (Twitter) in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/x.svg#x"></use></svg> </a><a class="nav-item nav-link nav-icon" href="https://www.youtube.com/@flutterdev" aria-label="Open Flutter's YouTube in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/youtube.svg#youtube"></use></svg> </a><a class="nav-item nav-link nav-icon" href="https://medium.com/flutter" aria-label="Open Flutter's Medium blog in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/medium.svg#medium"></use></svg> </a><a class="nav-item nav-link nav-icon" href="https://github.com/flutter" aria-label="Open Flutter's GitHub in a new tab" target="_blank" rel="noreferrer"><svg><use href="/assets/images/social/github.svg#github"></use></svg></a></div><a class="site-header__cta btn btn-primary" href="/get-started/install/">Get started</a></nav></header><div class="site-banner site-banner--default" role="alert"><a href="https://medium.com/flutter/flutter-3-24-dart-3-5-204b7d20c45d">Flutter 3.24 and Dart 3.5</a> are here! Check out <a href="/release/whats-new">what's new</a> on the website.</div><div class="container-fluid position-relative"><div class="row flex-xl-nowrap"><div class="fixed-col site-sidebar site-sidebar--fixed col-12 col-md-3 col-xl-2 d-none d-md-block" data-fixed-column><ul class="nav flex-column"><li class="nav-header">Get started</li><li class="nav-item"><a class="nav-link" href="/get-started/install">Set up Flutter</a></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" href="#fixed-sidenav-3" role="button" aria-expanded="true" aria-controls="fixed-sidenav-3">Learn Flutter</a><ul class="nav flex-column flex-nowrap collapse show" id="fixed-sidenav-3"><li class="nav-item"><a class="nav-link" href="/get-started/learn-flutter">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/codelab">Write your first app</a></li><li class="nav-item"><a class="nav-link active collapsible" data-toggle="collapse" data-target="#fixed-sidenav-3-3" href="#fixed-sidenav-3-3" role="button" aria-expanded="true" aria-controls="fixed-sidenav-3-3">Learn the fundamentals</a><ul class="nav flex-column flex-nowrap collapse show" id="fixed-sidenav-3-3"><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/dart">Intro to Dart</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/widgets">Widgets</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/layout">Layout</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/state-management">State management</a></li><li class="nav-item"><a class="nav-link active" href="/get-started/fundamentals/user-input">Handling user input</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/networking">Networking and data</a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/local-caching">Local data and caching</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-3-4" href="/get-started/flutter-for" role="button" aria-expanded="false" aria-controls="fixed-sidenav-3-4">From another platform?</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-3-4"><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/android-devs">Flutter for Android devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/swiftui-devs">Flutter for SwiftUI devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/uikit-devs">Flutter for UIKit devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/react-native-devs">Flutter for React Native devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/web-devs">Flutter for web devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/xamarin-forms-devs">Flutter for Xamarin.Forms devs</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/declarative">Introduction to declarative UI</a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/dart-swift-concurrency">Flutter versus Swift concurrency</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/codelabs">Codelabs</a></li><li class="nav-item"><a class="nav-link" href="/cookbook">Cookbook</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.github.io/samples/" target="_blank" rel="noopener">Demos and samples</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-4" role="button" aria-expanded="false" aria-controls="fixed-sidenav-4">Stay up to date</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-4"><li class="nav-item"><a class="nav-link" href="/release/upgrade">Upgrade</a></li><li class="nav-item"><a class="nav-link" href="/release/archive">SDK archive</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/release/whats-new">What's new</a></li><li class="nav-item"><a class="nav-link" href="/release/release-notes">Release notes</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes">Breaking changes</a></li><li class="nav-item"><a class="nav-link" href="/release/compatibility-policy">Compatibility policy</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-5" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5">App solutions</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-1" href="#fixed-sidenav-5-1" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-1">AI</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-1"><li class="nav-item"><a class="nav-link" href="/resources/ai-overview">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://ai.google.dev/gemini-api/docs/get-started/dart" target="_blank" rel="noopener">Get started with the Gemini API</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_generative_ai" target="_blank" rel="noopener">Google AI Dart SDK (pub.dev)</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=1AuzJEiHjO4" target="_blank" rel="noopener">Build with Google AI Dart SDK (video)</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-2" href="#fixed-sidenav-5-2" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-2">Firebase & Firestore</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter" target="_blank" rel="noopener">Discover Firebase for Flutter</a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=wUSkeTaBonA" target="_blank" rel="noopener">Get to know Firebase for Flutter</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">Add a user authentication flow to a Flutter app using FirebaseUI</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">Get to know Firebase for web</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-3" href="#fixed-sidenav-5-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-3">Games</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-3"><li class="nav-item"><a class="nav-link" href="/resources/games-toolkit">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/achievements-leaderboard">Add achievements and leaderboards</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">Build leaderboards with Firestore</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/firestore-multiplayer">Add multiplayer support</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">Add in-app purchases</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">Add user authentication</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">Debug using Crashlytics</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">Intro to Flame with Flutter</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4" href="#fixed-sidenav-5-4" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4">Monetization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4-1" href="#fixed-sidenav-5-4-1" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4-1">Advertising</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4-1"><li class="nav-item"><a class="nav-link" href="/resources/ads-overview">Ads overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads">Add advertising</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">Add AdMob ads to your Flutter app</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">Add an AdMob banner and native inline ads</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/admob/flutter/mediation" target="_blank" rel="noopener">Google AdMob mediation</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/interactive_media_ads" target="_blank" rel="noopener">Interactive Media Ads SDK</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4-2" href="#fixed-sidenav-5-4-2" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4-2">In-app purchases</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4-2"><li class="nav-item"><a class="nav-link" href="/resources/in-app-purchases-overview">In-app purchases overview</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">Add in-app purchases</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-4-3" href="#fixed-sidenav-5-4-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-4-3">Payments</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-4-3"><li class="nav-item"><a class="nav-link" href="/resources/payments-overview">Payments overview</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/pay" target="_blank" rel="noopener">Google pay package</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-5" href="#fixed-sidenav-5-5" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-5">Maps</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-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">Add Google maps to a Flutter app</a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/maps/flutter-package" target="_blank" rel="noopener">Google Maps package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-5-6" href="#fixed-sidenav-5-6" role="button" aria-expanded="false" aria-controls="fixed-sidenav-5-6">News</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/resources/news-toolkit">Build a news app</a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">User interface</li><li class="nav-item"><a class="nav-link" href="/ui">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/widgets">Widget catalog</a></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-10" role="button" aria-expanded="false" aria-controls="fixed-sidenav-10">Layout</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-10"><li class="nav-item"><a class="nav-link" href="/ui/layout">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/tutorial">Build a layout</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-10-3" href="/ui/layout/lists" role="button" aria-expanded="false" aria-controls="fixed-sidenav-10-3">Lists & grids</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-10-3"><li class="nav-item"><a class="nav-link" href="/cookbook/lists/basic-list">Create and use lists</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/horizontal-list">Create a horizontal list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/grid-lists">Create a grid view</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/mixed-list">Create lists with different types of items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/spaced-items">Create lists with spaced items</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/long-lists">Work with long lists</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-10-4" href="/ui/layout/scrolling" role="button" aria-expanded="false" aria-controls="fixed-sidenav-10-4">Scrolling</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-10-4"><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling/slivers">Use slivers to achieve fancy scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/floating-app-bar">Place a floating app bar above a list</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/parallax-scrolling">Create a scrolling parallax effect</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-11" role="button" aria-expanded="false" aria-controls="fixed-sidenav-11">Adaptive & responsive design</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-11"><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive">Overview</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/general">General approach</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/safearea-mediaquery">SafeArea & MediaQuery</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/large-screens">Large screens & foldables</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/input">User input & accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/capabilities">Capabilities & policies</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/best-practices">Best practices</a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/more-info">Additional resources</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-12" role="button" aria-expanded="false" aria-controls="fixed-sidenav-12">Design & theming</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-12"><li class="nav-item"><a class="nav-link" href="/cookbook/design/themes">Share styles with themes</a></li><li class="nav-item"><a class="nav-link" href="/ui/design/material">Material design</a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes/material-3-migration">Migrate to Material 3</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-12-4" href="/ui/design/text" role="button" aria-expanded="false" aria-controls="fixed-sidenav-12-4">Text</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-12-4"><li class="nav-item"><a class="nav-link" href="/ui/design/text/typography">Fonts & typography</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/fonts">Use a custom font</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/package-fonts">Export fonts from a package</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_fonts" target="_blank" rel="noopener">Google Fonts package</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-12-5" href="/ui/design/graphics" role="button" aria-expanded="false" aria-controls="fixed-sidenav-12-5">Custom graphics</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-12-5"><li class="nav-item"><a class="nav-link" href="/ui/design/graphics/fragment-shaders">Use custom fragment shaders</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-13" role="button" aria-expanded="false" aria-controls="fixed-sidenav-13">Interactivity</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-13"><li class="nav-item"><a class="nav-link" href="/ui/interactivity">Add interactivity to your app</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-13-2" href="/ui/interactivity/gestures" role="button" aria-expanded="false" aria-controls="fixed-sidenav-13-2">Gestures</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-13-2"><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/handling-taps">Handle taps</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures/drag-outside">Drag an object outside an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/drag-a-widget">Drag a UI element within an app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/ripples">Add Material touch ripples</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/dismissible">Implement swipe to dismiss</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-13-3" href="/ui/interactivity/input" role="button" aria-expanded="false" aria-controls="fixed-sidenav-13-3">Input & forms</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-13-3"><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-input">Create and style a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/retrieve-input">Retrieve the value of a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-field-changes">Handle changes to a text field</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/focus">Manage focus in text fields</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/validation">Build a form with validation</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/snackbars">Display a snackbar</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/actions-and-shortcuts">Implement actions & shortcuts</a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/focus">Manage keyboard focus</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-14" role="button" aria-expanded="false" aria-controls="fixed-sidenav-14">Assets & media</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-14"><li class="nav-item"><a class="nav-link" href="/ui/assets/assets-and-images">Add assets and images</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/network-image">Display images from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/fading-in-images">Fade in images with a placeholder</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/play-video">Play and pause a video</a></li><li class="nav-item"><a class="nav-link" href="/ui/assets/asset-transformation">Transform assets at build time</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-15" role="button" aria-expanded="false" aria-controls="fixed-sidenav-15">Navigation & routing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-15"><li class="nav-item"><a class="nav-link" href="/ui/navigation">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/tabs">Add tabs to your app</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/navigation-basics">Navigate to a new screen and back</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/passing-data">Send data to a new screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/returning-data">Return data from a screen</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/drawer">Add a drawer to a screen</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/deep-linking">Set up deep linking</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-app-links">Set up app links for Android</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-universal-links">Set up universal links for iOS</a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/url-strategies">Configure web URL strategies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-16" role="button" aria-expanded="false" aria-controls="fixed-sidenav-16">Animations & transitions</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-16"><li class="nav-item"><a class="nav-link" href="/ui/animations">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/tutorial">Tutorial</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/implicit-animations">Implicit animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/animated-container">Animate the properties of a container</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/opacity-animation">Fade a widget in and out</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/hero-animations">Hero animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/page-route-animation">Animate a page route transition</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/physics-simulation">Animate using a physics simulation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/staggered-animations">Staggered animations</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/staggered-menu-animation">Create a staggered menu animation</a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/overview">API overview</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-17" role="button" aria-expanded="false" aria-controls="fixed-sidenav-17">Accessibility & internationalization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-17"><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/accessibility">Accessibility</a></li><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/internationalization">Internationalization</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-header">Beyond UI</li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-20" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20">Data & backend</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20"><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-1" href="/data-and-backend/state-mgmt" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-1">State management</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-1"><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/intro">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/declarative">Think declaratively</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/ephemeral-vs-app">Ephemeral vs app state</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/simple">Simple app state management</a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/options">Options</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-2" href="/data-and-backend/networking" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-2">Networking & http</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/networking">Overview</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/fetch-data">Fetch data from the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/authenticated-requests">Make authenticated requests</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/send-data">Send data to the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/update-data">Update data over the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/delete-data">Delete data on the internet</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/web-sockets">Communicate with WebSockets</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-3" href="/data-and-backend/serialization" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-3">Serialization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-3"><li class="nav-item"><a class="nav-link" href="/data-and-backend/serialization/json">JSON serialization</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/background-parsing">Parse JSON in the background</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-4" href="/data-and-backend/persistence" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-4">Persistence</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-4"><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/key-value">Store key-value data on disk</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/reading-writing-files">Read and write files</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/sqlite">Persist data with SQLite</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-20-5" href="/data-and-backend/firebase" role="button" aria-expanded="false" aria-controls="fixed-sidenav-20-5">Firebase</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-20-5"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase">Overview</a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter/setup" target="_blank" rel="noopener">Add Firebase to your Flutter app</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/google-apis">Google APIs</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-21" role="button" aria-expanded="false" aria-controls="fixed-sidenav-21">App architecture</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-21"><li class="nav-item"><a class="nav-link" href="/app-architecture">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/concepts">Architecture concepts</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/guide">Guide to app architecture</a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/recommendations">Recommendations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-21-5" href="/cookbook/architecture" role="button" aria-expanded="false" aria-controls="fixed-sidenav-21-5">Design patterns</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-21-5"><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/optimistic-state">Optimistic state</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/key-value-data">Persistent storage architecture: Key-value data</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/sql">Persistent storage architecture: SQL</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/architecture/offline-first">Offline-first</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-22" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22">Platform integration</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22"><li class="nav-item"><a class="nav-link" href="/reference/supported-platforms">Supported platforms</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/desktop">Build desktop apps with Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-channels">Write platform-specific code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-adaptations">Automatic platform adaptations</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-5" href="/platform-integration/android" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-5">Android</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-5"><li class="nav-item"><a class="nav-link" href="/platform-integration/android/install-android">Add Android as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/splash-screen">Add a splash screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/predictive-back">Add predictive back</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/platform-views">Host a native Android view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/compose-activity">Launch a Jetpack Compose activity</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/restore-state-android">Restore state on Android</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/chromeos">Target ChromeOS with Android</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-6" href="/platform-integration/ios" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-6">iOS</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-6"><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/install-ios">Add iOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-latest">Flutter on latest iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/apple-frameworks">Leverage Apple's system libraries</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/launch-screen">Add a launch screen</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-app-clip">Add iOS App Clip support</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/app-extensions">Add iOS app extensions</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/platform-views">Host a native iOS view</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-debugging">Enable debugging on iOS</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/restore-state-ios">Restore state on iOS</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-7" href="/platform-integration/linux" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-7">Linux</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-7"><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/install-linux">Add Linux as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/building">Build a Linux app</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-8" href="/platform-integration/macos" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-8">macOS</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-8"><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/install-macos">Add macOS as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/building">Build a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/c-interop">Bind to native code</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/platform-views">Host a native macOS view</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-9" href="/platform-integration/web" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-9">Web</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-9"><li class="nav-item"><a class="nav-link" href="/platform-integration/web/">Web support in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/install-web">Add web as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/building">Build a web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/wasm">Compile to WebAssembly</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/initialization">Customize app initialization</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add Flutter to any web app</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-content-in-flutter">Web content in Flutter</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/renderers">Web renderers</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-images">Display images on the web</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/faq">Web FAQ</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-22-10" href="/platform-integration/windows" role="button" aria-expanded="false" aria-controls="fixed-sidenav-22-10">Windows</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-22-10"><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/install-windows">Add Windows as build target</a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/building">Build a Windows app</a></li></ul></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-23" role="button" aria-expanded="false" aria-controls="fixed-sidenav-23">Packages & plugins</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-23"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/using-packages">Use packages & plugins</a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/developing-packages">Develop packages & plugins</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-23-3" href="/packages-and-plugins/swift-package-manager" role="button" aria-expanded="false" aria-controls="fixed-sidenav-23-3">Swift Package Manager</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-23-3"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-app-developers">For app developers</a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-plugin-authors">For plugin authors</a></li></ul></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/favorites">Flutter Favorites</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/flutter" target="_blank" rel="noopener">Package repository</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-24" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24">Testing & debugging</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24"><li class="nav-header">Testing</li><li class="nav-item"><a class="nav-link" href="/testing/overview">Overview</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-24-3" href="#fixed-sidenav-24-3" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24-3">Unit testing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24-3"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/mocking">Mock dependencies</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-24-4" href="#fixed-sidenav-24-4" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24-4">Widget testing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24-4"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/finders">Find widgets</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/scrolling">Simulate scrolling</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/tap-drag">Simulate user interaction</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-24-5" href="#fixed-sidenav-24-5" role="button" aria-expanded="false" aria-controls="fixed-sidenav-24-5">Integration testing</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-24-5"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/introduction">Introduction</a></li><li class="nav-item"><a class="nav-link" href="/testing/integration-tests">Write and run an integration test</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/profiling">Profile an integration test</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/testing/testing-plugins">Test a plugin</a></li><li class="nav-item"><a class="nav-link" href="/testing/plugins-in-tests">Handle plugin code in tests</a></li><li class="nav-header">Debugging</li><li class="nav-item"><a class="nav-link" href="/testing/debugging">Debugging tools</a></li><li class="nav-item"><a class="nav-link" href="/testing/code-debugging">Debug your app programmatically</a></li><li class="nav-item"><a class="nav-link" href="/testing/native-debugging">Use a native language debugger</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/testing/common-errors">Common Flutter errors</a></li><li class="nav-item"><a class="nav-link" href="/testing/errors">Handle errors</a></li><li class="nav-item"><a class="nav-link" href="/cookbook/maintenance/error-reporting">Report errors to a service</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-25" role="button" aria-expanded="false" aria-controls="fixed-sidenav-25">Performance & optimization</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-25"><li class="nav-item"><a class="nav-link" href="/perf">Overview</a></li><li class="nav-item"><a class="nav-link" href="/perf/impeller">Impeller</a></li><li class="nav-item"><a class="nav-link" href="/perf/best-practices">Performance best practices</a></li><li class="nav-item"><a class="nav-link" href="/perf/app-size">App size</a></li><li class="nav-item"><a class="nav-link" href="/perf/deferred-components">Deferred components</a></li><li class="nav-item"><a class="nav-link" href="/perf/rendering-performance">Rendering performance</a></li><li class="nav-item"><a class="nav-link" href="/perf/ui-performance">Performance profiling</a></li><li class="nav-item"><a class="nav-link" href="/perf/web-performance">Performance profiling for web</a></li><li class="nav-item"><a class="nav-link" href="/perf/shader">Shader compilation jank</a></li><li class="nav-item"><a class="nav-link" href="/perf/metrics">Performance metrics</a></li><li class="nav-item"><a class="nav-link" href="/perf/isolates">Concurrency and isolates</a></li><li class="nav-item"><a class="nav-link" href="/perf/faq">Performance FAQ</a></li><li class="nav-item"><a class="nav-link" href="/perf/appendix">Appendix</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-26" role="button" aria-expanded="false" aria-controls="fixed-sidenav-26">Deployment</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-26"><li class="nav-item"><a class="nav-link" href="/deployment/obfuscate">Obfuscate Dart code</a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors">Create flavors of an app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/android">Build and release an Android app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/ios">Build and release an iOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/macos">Build and release a macOS app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/linux">Build and release a Linux app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/windows">Build and release a Windows app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/web">Build and release a web app</a></li><li class="nav-item"><a class="nav-link" href="/deployment/cd">Set up continuous deployment</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-27" role="button" aria-expanded="false" aria-controls="fixed-sidenav-27">Add to an existing app</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-27"><li class="nav-item"><a class="nav-link" href="/add-to-app">Introduction</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-27-2" href="/add-to-app/android" role="button" aria-expanded="false" aria-controls="fixed-sidenav-27-2">Add to an Android app</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-27-2"><li class="nav-item"><a class="nav-link" href="/add-to-app/android/project-setup">Set up Android project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-screen">Add a single Flutter screen</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-fragment">Add a Flutter Fragment</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-view">Add a Flutter View</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/plugin-setup">Use a Flutter plugin</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-27-3" href="/add-to-app/ios" role="button" aria-expanded="false" aria-controls="fixed-sidenav-27-3">Add to an iOS app</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-27-3"><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/project-setup">Set up iOS project</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/add-flutter-screen">Add a single Flutter screen</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web">Add to a web app</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/debugging">Debug embedded Flutter module</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/multiple-flutters">Add multiple Flutter instances</a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/performance">Loading sequence and performance</a></li></ul></li><li aria-hidden="true"><div class="sidebar-primary-divider"></div></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-29" role="button" aria-expanded="false" aria-controls="fixed-sidenav-29">Tools & editors</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-29"><li class="nav-item"><a class="nav-link" href="/tools/android-studio">Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code">Visual Studio Code</a></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-29-3" href="/tools/devtools" role="button" aria-expanded="false" aria-controls="fixed-sidenav-29-3">DevTools</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-29-3"><li class="nav-item"><a class="nav-link" href="/tools/devtools">Overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/android-studio">Run from Android Studio & IntelliJ</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/vscode">Run from VS Code</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cli">Run from command line</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/inspector">Flutter inspector</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/performance">Performance view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cpu-profiler">CPU Profiler view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/memory">Memory view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/console">Debug console view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/network">Network view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/debugger">Debugger</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/logging">Logging view</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/app-size">App size tool</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/extensions">DevTools extensions</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/deep-links">Validate deep links</a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/release-notes">Release notes</a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/sdk">SDK overview</a></li><li class="nav-item"><a class="nav-link" href="/tools/pubspec">Flutter's pubspec options</a></li><li class="nav-item"><a class="nav-link" href="/tools/flutter-fix">Automated fixes</a></li><li class="nav-item"><a class="nav-link" href="/tools/formatting">Code formatting</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-30" role="button" aria-expanded="false" aria-controls="fixed-sidenav-30">Flutter concepts</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-30"><li class="nav-item"><a class="nav-link" href="/resources/architectural-overview">Architectural overview</a></li><li class="nav-item"><a class="nav-link" href="/resources/inside-flutter">Inside Flutter</a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/constraints">Understanding constraints</a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes">Flutter's build modes</a></li><li class="nav-item"><a class="nav-link" href="/tools/hot-reload">Hot reload</a></li></ul></li><li class="nav-item"><a class="nav-link collapsed collapsible" data-toggle="collapse" href="#fixed-sidenav-31" role="button" aria-expanded="false" aria-controls="fixed-sidenav-31">Resources</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-31"><li class="nav-item"><a class="nav-link" href="/resources/faq">FAQ</a></li><li class="nav-item"><a class="nav-link" href="/resources/books">Books</a></li><li class="nav-item"><a class="nav-link" href="/resources/videos">Videos</a></li><li class="nav-item"><a class="nav-link" href="/resources/courses">Courses</a></li><li class="nav-item"><a class="nav-link" href="/resources/bootstrap-into-dart">Learn Dart</a></li><li class="nav-item"><a class="nav-link" href="/resources/support">Get support</a></li><div class="dropdown-divider"></div><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-31-8" href="#fixed-sidenav-31-8" role="button" aria-expanded="false" aria-controls="fixed-sidenav-31-8">Contribute</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-31-8"><li class="nav-item"><a class="nav-link" href="/resources/bug-reports">Create useful bug reports</a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener">Contribute to Flutter</a></li><li class="nav-item"><a class="nav-link" href="/resources/design-docs">Discover proposed features</a></li></ul></li><li class="nav-item"><a class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#fixed-sidenav-31-9" href="/reference" role="button" aria-expanded="false" aria-controls="fixed-sidenav-31-9">Reference</a><ul class="nav flex-column flex-nowrap collapse" id="fixed-sidenav-31-9"><li class="nav-item"><a class="nav-link" href="/dash">Who is Dash?</a></li><li class="nav-item"><a class="nav-link" href="/reference/widgets">Widget index</a></li><li class="nav-item"><a class="nav-link" href="/reference/flutter-cli">flutter CLI</a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev" target="_blank" rel="noopener">API docs</a></li></ul></li></ul></li></ul></div><main class="site-content col-12 col-md-9 offset-md-3 col-xl-8 offset-xl-2 col-xxl-8 offset-xxl-2"><div id="site-toc--side" class="site-toc fixed-col col-xl-2 order-3" data-fixed-column><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#introduction-to-handling-user-input">Introduction to handling user input</a></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#buttons">Buttons</a></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#text">Text</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#selectabletext">SelectableText</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#richtext">RichText</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#textfield">TextField</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#form">Form</a></li></ul></li><li class="toc-entry nav-item toc-h2"><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 toc-h3"><a class="nav-link" href="#segmentedbutton">SegmentedButton</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#chip">Chip</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#dropdownmenu">DropdownMenu</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#slider">Slider</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#toggle-between-values">Toggle between values</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#checkbox-switch-and-radio">Checkbox, Switch, and Radio</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#checkbox">Checkbox</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#switch">Switch</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#radio">Radio</a></li></ul></li><li class="toc-entry nav-item toc-h2"><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 toc-h3"><a class="nav-link" href="#datepickerdialog">DatePickerDialog</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#timepickerdialog">TimePickerDialog</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#swipe-slide">Swipe & slide</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#dismissible">Dismissible</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#looking-for-more-widgets">Looking for more widgets?</a></li><li class="toc-entry nav-item toc-h2"><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 toc-h3"><a class="nav-link" href="#dont-forget-about-accessibility">Don't forget about accessibility!</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#testing">Testing</a></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#next-networking">Next: Networking</a></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#feedback">Feedback</a></li></ul></div><div class="container"><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><header class="site-content__title" id="site-content-title"><h1>Handling user input</h1><nav class="breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb-list" 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-outlined 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-outlined 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 toc-h2"><a href="#introduction-to-handling-user-input">Introduction to handling user input</a></li><li class="toc-entry toc-h2"><a href="#buttons">Buttons</a></li><li class="toc-entry toc-h2"><a href="#text">Text</a><ul><li class="toc-entry toc-h3"><a href="#selectabletext">SelectableText</a></li><li class="toc-entry toc-h3"><a href="#richtext">RichText</a></li><li class="toc-entry toc-h3"><a href="#textfield">TextField</a></li><li class="toc-entry toc-h3"><a href="#form">Form</a></li></ul></li><li class="toc-entry toc-h2"><a href="#select-a-value-from-a-group-of-options">Select a value from a group of options</a><ul><li class="toc-entry toc-h3"><a href="#segmentedbutton">SegmentedButton</a></li><li class="toc-entry toc-h3"><a href="#chip">Chip</a></li><li class="toc-entry toc-h3"><a href="#dropdownmenu">DropdownMenu</a></li><li class="toc-entry toc-h3"><a href="#slider">Slider</a></li></ul></li><li class="toc-entry toc-h2"><a href="#toggle-between-values">Toggle between values</a><ul><li class="toc-entry toc-h3"><a href="#checkbox-switch-and-radio">Checkbox, Switch, and Radio</a></li><li class="toc-entry toc-h3"><a href="#checkbox">Checkbox</a></li><li class="toc-entry toc-h3"><a href="#switch">Switch</a></li><li class="toc-entry toc-h3"><a href="#radio">Radio</a></li></ul></li><li class="toc-entry toc-h2"><a href="#select-a-date-or-time">Select a date or time</a><ul><li class="toc-entry toc-h3"><a href="#datepickerdialog">DatePickerDialog</a></li><li class="toc-entry toc-h3"><a href="#timepickerdialog">TimePickerDialog</a></li></ul></li><li class="toc-entry toc-h2"><a href="#swipe-slide">Swipe & slide</a><ul><li class="toc-entry toc-h3"><a href="#dismissible">Dismissible</a></li></ul></li><li class="toc-entry toc-h2"><a href="#looking-for-more-widgets">Looking for more widgets?</a></li><li class="toc-entry toc-h2"><a href="#build-interactive-widgets-with-gesturedetector">Build interactive widgets with GestureDetector</a><ul><li class="toc-entry toc-h3"><a href="#dont-forget-about-accessibility">Don't forget about accessibility!</a></li></ul></li><li class="toc-entry toc-h2"><a href="#testing">Testing</a></li><li class="toc-entry toc-h2"><a href="#next-networking">Next: Networking</a></li><li class="toc-entry toc-h2"><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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows an ElevatedButton with the text "Enabled" being clicked.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a cursor highlighting a portion of a string of text.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a string of text formatted with different text styles.</figcaption></div><p></p></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://flutter.github.io/samples/rich_text_editor.html">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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows text being typed into a TextField with a selected border and label.</figcaption></div><p></p></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://flutter.github.io/samples/web/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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a SegmentedButton, each segment with an icon and text representing its value.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows two rows of Chip widgets, each containing a circular leading profile image and content text.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a DropdownMenu widget with 5 value options. Each option's text color is styled to represent the color value.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">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><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a checkbox being checked and unchecked.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a Switch widget that is toggled on and off.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">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><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a column containing a CheckboxListTile and a SwitchListTile being toggled.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a DatePicker that is displayed when the "Pick a date" button is clicked.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">This figure shows a TimePicker that is displayed when the "Pick a time" button is clicked.</figcaption></div><p></p></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=""><div class="row"><div class="col-md-7" style="padding-right:12px"><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><p></p></div><div class="col-md-5" style="padding-left:0"><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" style="margin-top: 6px">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><p></p></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://flutter.github.io/samples/web/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 2024-09-26.</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></div></main></div></div><footer class="site-footer"><div class="container-fluid"><div class="row"><div class="col-md-12 site-footer__wrapper"><div class="site-footer__logo"><img src="/assets/images/branding/flutter/logo/flutter-mono-81x100.png" alt="Flutter Logo" width="81" height="100"></div><div class="site-footer__content"><ul class="site-footer__link-list"><li><a href="/tos">terms</a></li><li><a href="/brand">brand usage</a></li><li><a href="/security">security</a></li><li><a href="https://www.google.com/intl/en/policies/privacy">privacy</a></li><li><a href="https://esflutter.dev/">español</a></li><li><a href="https://flutter.cn" class="text-nowrap">社区中文资源</a></li><li><a href="https://blog.google/inside-google/company-announcements/standing-with-black-community">We stand in solidarity with the Black community. Black Lives Matter.</a></li></ul><p class="licenses">Except as otherwise noted, this work is licensed under a <a rel="license" href="https://creativecommons.org/licenses/by/4.0">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the BSD License.</p></div></div></div></div></footer><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js" integrity="sha512-7rusk8kGPFynZWu26OKbTeI+QPoYchtxsmPeBqkHIEXJxeun4yJ4ISYe7C6sz9wdxeE1Gk3VxsIWgCZTc+vX3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script><script src="/assets/js/tabs.js"></script><script src="/assets/js/archive.js"></script><script src="/assets/js/main.js"></script></body></html>