CINXE.COM

Flutter for Android developers | Flutter

<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Flutter for Android developers | 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 apply Android developer knowledge when building Flutter apps."><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@flutterdev"><meta property="og:title" content="Flutter for Android developers"><meta property="og:url" content="https://docs.flutter.dev/get-started/flutter-for/android-devs"><meta property="og:description" content="Learn how to apply Android developer knowledge when building Flutter apps."><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 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" 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 active collapsible" data-toggle="collapse" data-target="#header-sidenav-3-4" href="/get-started/flutter-for" role="button" aria-expanded="true" aria-controls="header-sidenav-3-4">From another platform?</a><ul class="nav flex-column flex-nowrap collapse show" id="header-sidenav-3-4"><li class="nav-item"><a class="nav-link active" 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 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" 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 active collapsible" data-toggle="collapse" data-target="#fixed-sidenav-3-4" href="/get-started/flutter-for" role="button" aria-expanded="true" aria-controls="fixed-sidenav-3-4">From another platform?</a><ul class="nav flex-column flex-nowrap collapse show" id="fixed-sidenav-3-4"><li class="nav-item"><a class="nav-link active" 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="#views">Views</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-a-view-in-flutter">What is the equivalent of a View in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-update-widgets">How do I update widgets?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-lay-out-my-widgets-where-is-my-xml-layout-file">How do I lay out my widgets? Where is my XML layout file?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-add-or-remove-a-component-from-my-layout">How do I add or remove a component from my layout?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-animate-a-widget">How do I animate a widget?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-use-a-canvas-to-drawpaint">How do I use a Canvas to draw/paint?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-build-custom-widgets">How do I build custom widgets?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#intents">Intents</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-an-intent-in-flutter">What is the equivalent of an Intent in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-handle-incoming-intents-from-external-applications-in-flutter">How do I handle incoming intents from external applications in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-startactivityforresult">What is the equivalent of startActivityForResult()?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#async-ui">Async UI</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-runonuithread-in-flutter">What is the equivalent of runOnUiThread() in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-you-move-work-to-a-background-thread">How do you move work to a background thread?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-okhttp-on-flutter">What is the equivalent of OkHttp on Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-show-the-progress-for-a-long-running-task">How do I show the progress for a long-running task?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#project-structure-resources">Project structure &amp; resources</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#where-do-i-store-my-resolution-dependent-image-files">Where do I store my resolution-dependent image files?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#where-do-i-store-strings-how-do-i-handle-localization">Where do I store strings? How do I handle localization?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-a-gradle-file-how-do-i-add-dependencies">What is the equivalent of a Gradle file? How do I add dependencies?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#activities-and-fragments">Activities and fragments</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-are-the-equivalent-of-activities-and-fragments-in-flutter">What are the equivalent of activities and fragments in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-listen-to-android-activity-lifecycle-events">How do I listen to Android activity lifecycle events?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#layouts">Layouts</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-a-linearlayout">What is the equivalent of a LinearLayout?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-a-relativelayout">What is the equivalent of a RelativeLayout?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-a-scrollview">What is the equivalent of a ScrollView?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-handle-landscape-transitions-in-flutter">How do I handle landscape transitions in Flutter?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#gesture-detection-and-touch-event-handling">Gesture detection and touch event handling</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-add-an-onclick-listener-to-a-widget-in-flutter">How do I add an onClick listener to a widget in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-handle-other-gestures-on-widgets">How do I handle other gestures on widgets?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#listviews-adapters">Listviews &amp; adapters</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-alternative-to-a-listview-in-flutter">What is the alternative to a ListView in Flutter?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-know-which-list-item-is-clicked-on">How do I know which list item is clicked on?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-update-listviews-dynamically">How do I update ListView's dynamically?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#working-with-text">Working with text</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-set-custom-fonts-on-my-text-widgets">How do I set custom fonts on my Text widgets?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-style-my-text-widgets">How do I style my Text widgets?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#form-input">Form input</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-is-the-equivalent-of-a-hint-on-an-input">What is the equivalent of a &quot;hint&quot; on an Input?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-show-validation-errors">How do I show validation errors?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#flutter-plugins">Flutter plugins</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-access-the-gps-sensor">How do I access the GPS sensor?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-access-the-camera">How do I access the camera?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-log-in-with-facebook">How do I log in with Facebook?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-use-firebase-features">How do I use Firebase features?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-build-my-own-custom-native-integrations">How do I build my own custom native integrations?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-use-the-ndk-in-my-flutter-application">How do I use the NDK in my Flutter application?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#themes">Themes</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-theme-my-app">How do I theme my app?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#databases-and-local-storage">Databases and local storage</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-access-shared-preferences">How do I access Shared Preferences?</a></li><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-access-sqlite-in-flutter">How do I access SQLite in Flutter?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#debugging">Debugging</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#what-tools-can-i-use-to-debug-my-app-in-flutter">What tools can I use to debug my app in Flutter?</a></li></ul></li><li class="toc-entry nav-item toc-h2"><a class="nav-link" href="#notifications">Notifications</a><ul class="nav"><li class="toc-entry nav-item toc-h3"><a class="nav-link" href="#how-do-i-set-up-push-notifications">How do I set up push notifications?</a></li></ul></li></ul></div><div class="container"><header class="site-content__title" id="site-content-title"><h1>Flutter for Android developers</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/flutter-for" property="item" typeof="WebPage"><span property="name">Flutter for</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/flutter-for/android-devs" property="item" typeof="WebPage"><span property="name">Flutter for Android developers</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="#views">Views</a><ul><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-a-view-in-flutter">What is the equivalent of a View in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-update-widgets">How do I update widgets?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-lay-out-my-widgets-where-is-my-xml-layout-file">How do I lay out my widgets? Where is my XML layout file?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-add-or-remove-a-component-from-my-layout">How do I add or remove a component from my layout?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-animate-a-widget">How do I animate a widget?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-use-a-canvas-to-drawpaint">How do I use a Canvas to draw/paint?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-build-custom-widgets">How do I build custom widgets?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#intents">Intents</a><ul><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-an-intent-in-flutter">What is the equivalent of an Intent in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-handle-incoming-intents-from-external-applications-in-flutter">How do I handle incoming intents from external applications in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-startactivityforresult">What is the equivalent of startActivityForResult()?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#async-ui">Async UI</a><ul><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-runonuithread-in-flutter">What is the equivalent of runOnUiThread() in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-you-move-work-to-a-background-thread">How do you move work to a background thread?</a></li><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-okhttp-on-flutter">What is the equivalent of OkHttp on Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-show-the-progress-for-a-long-running-task">How do I show the progress for a long-running task?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#project-structure-resources">Project structure &amp; resources</a><ul><li class="toc-entry toc-h3"><a href="#where-do-i-store-my-resolution-dependent-image-files">Where do I store my resolution-dependent image files?</a></li><li class="toc-entry toc-h3"><a href="#where-do-i-store-strings-how-do-i-handle-localization">Where do I store strings? How do I handle localization?</a></li><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-a-gradle-file-how-do-i-add-dependencies">What is the equivalent of a Gradle file? How do I add dependencies?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#activities-and-fragments">Activities and fragments</a><ul><li class="toc-entry toc-h3"><a href="#what-are-the-equivalent-of-activities-and-fragments-in-flutter">What are the equivalent of activities and fragments in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-listen-to-android-activity-lifecycle-events">How do I listen to Android activity lifecycle events?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#layouts">Layouts</a><ul><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-a-linearlayout">What is the equivalent of a LinearLayout?</a></li><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-a-relativelayout">What is the equivalent of a RelativeLayout?</a></li><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-a-scrollview">What is the equivalent of a ScrollView?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-handle-landscape-transitions-in-flutter">How do I handle landscape transitions in Flutter?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#gesture-detection-and-touch-event-handling">Gesture detection and touch event handling</a><ul><li class="toc-entry toc-h3"><a href="#how-do-i-add-an-onclick-listener-to-a-widget-in-flutter">How do I add an onClick listener to a widget in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-handle-other-gestures-on-widgets">How do I handle other gestures on widgets?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#listviews-adapters">Listviews &amp; adapters</a><ul><li class="toc-entry toc-h3"><a href="#what-is-the-alternative-to-a-listview-in-flutter">What is the alternative to a ListView in Flutter?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-know-which-list-item-is-clicked-on">How do I know which list item is clicked on?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-update-listviews-dynamically">How do I update ListView's dynamically?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#working-with-text">Working with text</a><ul><li class="toc-entry toc-h3"><a href="#how-do-i-set-custom-fonts-on-my-text-widgets">How do I set custom fonts on my Text widgets?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-style-my-text-widgets">How do I style my Text widgets?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#form-input">Form input</a><ul><li class="toc-entry toc-h3"><a href="#what-is-the-equivalent-of-a-hint-on-an-input">What is the equivalent of a &quot;hint&quot; on an Input?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-show-validation-errors">How do I show validation errors?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#flutter-plugins">Flutter plugins</a><ul><li class="toc-entry toc-h3"><a href="#how-do-i-access-the-gps-sensor">How do I access the GPS sensor?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-access-the-camera">How do I access the camera?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-log-in-with-facebook">How do I log in with Facebook?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-use-firebase-features">How do I use Firebase features?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-build-my-own-custom-native-integrations">How do I build my own custom native integrations?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-use-the-ndk-in-my-flutter-application">How do I use the NDK in my Flutter application?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#themes">Themes</a><ul><li class="toc-entry toc-h3"><a href="#how-do-i-theme-my-app">How do I theme my app?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#databases-and-local-storage">Databases and local storage</a><ul><li class="toc-entry toc-h3"><a href="#how-do-i-access-shared-preferences">How do I access Shared Preferences?</a></li><li class="toc-entry toc-h3"><a href="#how-do-i-access-sqlite-in-flutter">How do I access SQLite in Flutter?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#debugging">Debugging</a><ul><li class="toc-entry toc-h3"><a href="#what-tools-can-i-use-to-debug-my-app-in-flutter">What tools can I use to debug my app in Flutter?</a></li></ul></li><li class="toc-entry toc-h2"><a href="#notifications">Notifications</a><ul><li class="toc-entry toc-h3"><a href="#how-do-i-set-up-push-notifications">How do I set up push notifications?</a></li></ul></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> <?code-excerpt path-base="get-started/flutter-for/android_devs"?> <p>This document is meant for Android developers looking to apply their existing Android knowledge to build mobile apps with Flutter. If you understand the fundamentals of the Android framework then you can use this document as a jump start to Flutter development.</p><aside class="alert alert-info"><div class="alert-header"><i class="material-symbols" aria-hidden="true">info</i> <span>Note</span></div><div class="alert-content"><p>To integrate Flutter code into your Android app, see <a href="/add-to-app">Add Flutter to existing app</a>.</p></div></aside><p>Your Android knowledge and skill set are highly valuable when building with Flutter, because Flutter relies on the mobile operating system for numerous capabilities and configurations. Flutter is a new way to build UIs for mobile, but it has a plugin system to communicate with Android (and iOS) for non-UI tasks. If you're an expert with Android, you don't have to relearn everything to use Flutter.</p><p>This document can be used as a cookbook by jumping around and finding questions that are most relevant to your needs.</p><div class="header-wrapper"><h2 id="views">Views</h2><a class="heading-link" href="#views" aria-label="Link to 'Views' section">#</a></div><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-a-view-in-flutter">What is the equivalent of a View in Flutter?</h3><a class="heading-link" href="#what-is-the-equivalent-of-a-view-in-flutter" aria-label="Link to 'What is the equivalent of a View in Flutter?' section">#</a></div><aside class="alert alert-secondary"><div class="alert-header"><span></span></div><div class="alert-content"><p>How is react-style, or <em>declarative</em>, programming different than the traditional imperative style? For a comparison, see <a href="/get-started/flutter-for/declarative">Introduction to declarative UI</a>.</p></div></aside><p>In Android, the <code>View</code> is the foundation of everything that shows up on the screen. Buttons, toolbars, and inputs, everything is a View. In Flutter, the rough equivalent to a <code>View</code> is a <code>Widget</code>. Widgets don't map exactly to Android views, but while you're getting acquainted with how Flutter works you can think of them as &quot;the way you declare and construct UI&quot;.</p><p>However, these have a few differences to a <code>View</code>. To start, widgets have a different lifespan: they are immutable and only exist until they need to be changed. Whenever widgets or their state change, Flutter's framework creates a new tree of widget instances. In comparison, an Android view is drawn once and does not redraw until <code>invalidate</code> is called.</p><p>Flutter's widgets are lightweight, in part due to their immutability. Because they aren't views themselves, and aren't directly drawing anything, but rather are a description of the UI and its semantics that get &quot;inflated&quot; into actual view objects under the hood.</p><p>Flutter includes the <a href="https://m3.material.io/develop/flutter">Material Components</a> library. These are widgets that implement the <a href="https://m3.material.io/styles">Material Design guidelines</a>. Material Design is a flexible design system <a href="https://m3.material.io/develop">optimized for all platforms</a>, including iOS.</p><p>But Flutter is flexible and expressive enough to implement any design language. For example, on iOS, you can use the <a href="/ui/widgets/cupertino">Cupertino widgets</a> to produce an interface that looks like <a href="https://developer.apple.com/design/resources/">Apple's iOS design language</a>.</p><div class="header-wrapper"><h3 id="how-do-i-update-widgets">How do I update widgets?</h3><a class="heading-link" href="#how-do-i-update-widgets" aria-label="Link to 'How do I update widgets?' section">#</a></div><p>In Android, you update your views by directly mutating them. However, in Flutter, <code>Widget</code>s are immutable and are not updated directly, instead you have to work with the widget's state.</p><p>This is where the concept of <code>Stateful</code> and <code>Stateless</code> widgets comes from. A <code>StatelessWidget</code> is just what it sounds like—a widget with no state information.</p><p><code>StatelessWidgets</code> are useful when the part of the user interface you are describing does not depend on anything other than the configuration information in the object.</p><p>For example, in Android, this is similar to placing an <code>ImageView</code> with your logo. The logo is not going to change during runtime, so use a <code>StatelessWidget</code> in Flutter.</p><p>If you want to dynamically change the UI based on data received after making an HTTP call or user interaction then you have to work with <code>StatefulWidget</code> and tell the Flutter framework that the widget's <code>State</code> has been updated so it can update that widget.</p><p>The important thing to note here is at the core both stateless and stateful widgets behave the same. They rebuild every frame, the difference is the <code>StatefulWidget</code> has a <code>State</code> object that stores state data across frames and restores it.</p><p>If you are in doubt, then always remember this rule: if a widget changes (because of user interactions, for example) it's stateful. However, if a widget reacts to change, the containing parent widget can still be stateless if it doesn't itself react to change.</p><p>The following example shows how to use a <code>StatelessWidget</code>. A common <code>StatelessWidget</code> is the <code>Text</code> widget. If you look at the implementation of the <code>Text</code> widget you'll find that it subclasses <code>StatelessWidget</code>.</p> <?code-excerpt "lib/text_widget.dart (text-widget)" replace="/return const //g"?> <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">Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#0C7064"> 'I like Flutter!'</span><span style="color:#222222">,</span></span> <span class="line"><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:#222222">);</span></span></code></pre></div></div><p>As you can see, the <code>Text</code> Widget has no state information associated with it, it renders what is passed in its constructors and nothing more.</p><p>But, what if you want to make &quot;I Like Flutter&quot; change dynamically, for example when clicking a <code>FloatingActionButton</code>?</p><p>To achieve this, wrap the <code>Text</code> widget in a <code>StatefulWidget</code> and update it when the user clicks the button.</p><p>For example:</p> <?code-excerpt "lib/text_widget.dart (stateful-widget)"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#6E6E70"> // Default placeholder text.</span></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> textToShow = </span><span style="color:#0C7064">'I Like Flutter'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> _updateText</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#6E6E70"> // Update the text.</span></span> <span class="line"><span style="color:#222222"> textToShow = </span><span style="color:#0C7064">'Flutter is Awesome!'</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> <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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(textToShow)),</span></span> <span class="line"><span style="color:#222222"> floatingActionButton: </span><span style="color:#0468D7">FloatingActionButton</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onPressed: _updateText,</span></span> <span class="line"><span style="color:#222222"> tooltip: </span><span style="color:#0C7064">'Update Text'</span><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"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.update),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-lay-out-my-widgets-where-is-my-xml-layout-file">How do I lay out my widgets? Where is my XML layout file?</h3><a class="heading-link" href="#how-do-i-lay-out-my-widgets-where-is-my-xml-layout-file" aria-label="Link to 'How do I lay out my widgets? Where is my XML layout file?' section">#</a></div><p>In Android, you write layouts in XML, but in Flutter you write your layouts with a widget tree.</p><p>The following example shows how to display a simple widget with padding:</p> <?code-excerpt "lib/layout.dart (simple-widget)"?> <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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</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"> 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"> padding: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> EdgeInsets</span><span style="color:#222222">.</span><span style="color:#6200EE">only</span><span style="color:#222222">(left: </span><span style="color:#0C7064">20</span><span style="color:#222222">, right: </span><span style="color:#0C7064">30</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:#222222"> child: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Hello'</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>You can view some of the layouts that Flutter has to offer in the <a href="/ui/widgets/layout">widget catalog</a>.</p><div class="header-wrapper"><h3 id="how-do-i-add-or-remove-a-component-from-my-layout">How do I add or remove a component from my layout?</h3><a class="heading-link" href="#how-do-i-add-or-remove-a-component-from-my-layout" aria-label="Link to 'How do I add or remove a component from my layout?' section">#</a></div><p>In Android, you call <code>addChild()</code> or <code>removeChild()</code> on a parent to dynamically add or remove child views. In Flutter, because widgets are immutable there is no direct equivalent to <code>addChild()</code>. Instead, you can pass a function to the parent that returns a widget, and control that child's creation with a boolean flag.</p><p>For example, here is how you can toggle between two widgets when you click on a <code>FloatingActionButton</code>:</p> <?code-excerpt "lib/layout.dart (toggle-widget)"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</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:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#6E6E70"> // Default value for toggle.</span></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#222222"> toggle = </span><span style="color:#0C7064">true</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> _toggle</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> toggle = !toggle;</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:#0468D7"> Widget</span><span style="color:#6200EE"> _getToggleChild</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (toggle) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#BD2314"> const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Toggle One'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#BD2314">else</span><span style="color:#222222"> {</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"> onPressed: () {},</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">'Toggle Two'</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> <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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#6200EE">_getToggleChild</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> floatingActionButton: </span><span style="color:#0468D7">FloatingActionButton</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onPressed: _toggle,</span></span> <span class="line"><span style="color:#222222"> tooltip: </span><span style="color:#0C7064">'Update Text'</span><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"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.update),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-animate-a-widget">How do I animate a widget?</h3><a class="heading-link" href="#how-do-i-animate-a-widget" aria-label="Link to 'How do I animate a widget?' section">#</a></div><p>In Android, you either create animations using XML, or call the <code>animate()</code> method on a view. In Flutter, animate widgets using the animation library by wrapping widgets inside an animated widget.</p><p>In Flutter, use an <code>AnimationController</code> which is an <code>Animation&lt;double&gt;</code> that can pause, seek, stop and reverse the animation. It requires a <code>Ticker</code> that signals when vsync happens, and produces a linear interpolation between 0 and 1 on each frame while it's running. You then create one or more <code>Animation</code>s and attach them to the controller.</p><p>For example, you might use <code>CurvedAnimation</code> to implement an animation along an interpolated curve. In this sense, the controller is the &quot;master&quot; source of the animation progress and the <code>CurvedAnimation</code> computes the curve that replaces the controller's default linear motion. Like widgets, animations in Flutter work with composition.</p><p>When building the widget tree you assign the <code>Animation</code> to an animated property of a widget, such as the opacity of a <code>FadeTransition</code>, and tell the controller to start the animation.</p><p>The following example shows how to write a <code>FadeTransition</code> that fades the widget into a logo when you press the <code>FloatingActionButton</code>:</p> <?code-excerpt "lib/animation.dart"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> FadeAppTest</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"> FadeAppTest</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> FadeAppTest</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Fade Demo'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> MyFadeTest</span><span style="color:#222222">(title: </span><span style="color:#0C7064">'Fade Demo'</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> MyFadeTest</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"> MyFadeTest</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key, </span><span style="color:#BD2314">required</span><span style="color:#BD2314"> this</span><span style="color:#222222">.title});</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#0468D7"> String</span><span style="color:#222222"> title;</span></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">MyFadeTest</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_MyFadeTest</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"> _MyFadeTest</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">MyFadeTest</span><span style="color:#222222">> </span><span style="color:#BD2314">with</span><span style="color:#0468D7"> TickerProviderStateMixin</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> late</span><span style="color:#0468D7"> AnimationController</span><span style="color:#222222"> controller;</span></span> <span class="line"><span style="color:#BD2314"> late</span><span style="color:#0468D7"> CurvedAnimation</span><span style="color:#222222"> curve;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> controller = </span><span style="color:#0468D7">AnimationController</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> duration: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(milliseconds: </span><span style="color:#0C7064">2000</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> vsync: </span><span style="color:#BD2314">this</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> curve = </span><span style="color:#0468D7">CurvedAnimation</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> parent: controller,</span></span> <span class="line"><span style="color:#222222"> curve: </span><span style="color:#0468D7">Curves</span><span style="color:#222222">.easeIn,</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">(widget.title),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">FadeTransition</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> opacity: curve,</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> FlutterLogo</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> size: </span><span style="color:#0C7064">100</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"> floatingActionButton: </span><span style="color:#0468D7">FloatingActionButton</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> tooltip: </span><span style="color:#0C7064">'Fade'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> onPressed: () {</span></span> <span class="line"><span style="color:#222222"> controller.</span><span style="color:#6200EE">forward</span><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"> Icon</span><span style="color:#222222">(</span><span style="color:#0468D7">Icons</span><span style="color:#222222">.brush),</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>For more information, see <a href="/ui/widgets/animation">Animation &amp; Motion widgets</a>, the <a href="/ui/animations/tutorial">Animations tutorial</a>, and the <a href="/ui/animations">Animations overview</a>.</p><div class="header-wrapper"><h3 id="how-do-i-use-a-canvas-to-drawpaint">How do I use a Canvas to draw/paint?</h3><a class="heading-link" href="#how-do-i-use-a-canvas-to-drawpaint" aria-label="Link to 'How do I use a Canvas to draw/paint?' section">#</a></div><p>In Android, you would use the <code>Canvas</code> and <code>Drawable</code> to draw images and shapes to the screen. Flutter has a similar <code>Canvas</code> API as well, since it's based on the same low-level rendering engine, Skia. As a result, painting to a canvas in Flutter is a very familiar task for Android developers.</p><p>Flutter has two classes that help you draw to the canvas: <code>CustomPaint</code> and <code>CustomPainter</code>, the latter of which implements your algorithm to draw to the canvas.</p><p>To learn how to implement a signature painter in Flutter, see Collin's answer on <a href="https://stackoverflow.com/questions/46241071/create-signature-area-for-mobile-app-in-dart-flutter">Custom Paint</a>.</p> <?code-excerpt "lib/canvas.dart"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() => </span><span style="color:#6200EE">runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> MaterialApp</span><span style="color:#222222">(home: </span><span style="color:#0468D7">DemoApp</span><span style="color:#222222">()));</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> DemoApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> DemoApp</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"> 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 style="color:#BD2314">const</span><span style="color:#0468D7"> Scaffold</span><span style="color:#222222">(body: </span><span style="color:#0468D7">Signature</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"> Signature</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"> Signature</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"> SignatureState</span><span style="color:#6200EE"> createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">SignatureState</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"> SignatureState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Signature</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Offset</span><span style="color:#222222">?> _points = &#x3C;</span><span style="color:#0468D7">Offset</span><span style="color:#222222">>[];</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"> GestureDetector</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onPanUpdate: (details) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#0468D7"> RenderBox</span><span style="color:#222222">? referenceBox = context.</span><span style="color:#6200EE">findRenderObject</span><span style="color:#222222">() </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> RenderBox</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#0468D7"> Offset</span><span style="color:#222222"> localPosition =</span></span> <span class="line"><span style="color:#222222"> referenceBox.</span><span style="color:#6200EE">globalToLocal</span><span style="color:#222222">(details.globalPosition);</span></span> <span class="line"><span style="color:#222222"> _points = </span><span style="color:#0468D7">List</span><span style="color:#222222">.</span><span style="color:#6200EE">from</span><span style="color:#222222">(_points)..</span><span style="color:#6200EE">add</span><span style="color:#222222">(localPosition);</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"> onPanEnd: (details) => _points.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span><span style="color:#0C7064">null</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">CustomPaint</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> painter: </span><span style="color:#0468D7">SignaturePainter</span><span style="color:#222222">(_points),</span></span> <span class="line"><span style="color:#222222"> size: </span><span style="color:#0468D7">Size</span><span style="color:#222222">.infinite,</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SignaturePainter</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> CustomPainter</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#0468D7"> SignaturePainter</span><span style="color:#222222">(</span><span style="color:#BD2314">this</span><span style="color:#222222">.points);</span></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Offset</span><span style="color:#222222">?> points;</span></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> paint</span><span style="color:#222222">(</span><span style="color:#0468D7">Canvas</span><span style="color:#222222"> canvas, </span><span style="color:#0468D7">Size</span><span style="color:#222222"> size) {</span></span> <span class="line"><span style="color:#BD2314"> var</span><span style="color:#222222"> paint = </span><span style="color:#0468D7">Paint</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">.black</span></span> <span class="line"><span style="color:#222222"> ..strokeCap = </span><span style="color:#0468D7">StrokeCap</span><span style="color:#222222">.round</span></span> <span class="line"><span style="color:#222222"> ..strokeWidth = </span><span style="color:#0C7064">5</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#0468D7">int</span><span style="color:#222222"> i = </span><span style="color:#0C7064">0</span><span style="color:#222222">; i &#x3C; points.length - </span><span style="color:#0C7064">1</span><span style="color:#222222">; i++) {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (points[i] != </span><span style="color:#0C7064">null</span><span style="color:#222222"> &#x26;&#x26; points[i + </span><span style="color:#0C7064">1</span><span style="color:#222222">] != </span><span style="color:#0C7064">null</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#222222"> canvas.</span><span style="color:#6200EE">drawLine</span><span style="color:#222222">(points[i]!, points[i + </span><span style="color:#0C7064">1</span><span style="color:#222222">]!, paint);</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> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#6200EE"> shouldRepaint</span><span style="color:#222222">(</span><span style="color:#0468D7">SignaturePainter</span><span style="color:#222222"> oldDelegate) =></span></span> <span class="line"><span style="color:#222222"> oldDelegate.points != points;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-build-custom-widgets">How do I build custom widgets?</h3><a class="heading-link" href="#how-do-i-build-custom-widgets" aria-label="Link to 'How do I build custom widgets?' section">#</a></div><p>In Android, you typically subclass <code>View</code>, or use a pre-existing view, to override and implement methods that achieve the desired behavior.</p><p>In Flutter, build a custom widget by <a href="/resources/architectural-overview#composition">composing</a> smaller widgets (instead of extending them). It is somewhat similar to implementing a custom <code>ViewGroup</code> in Android, where all the building blocks are already existing, but you provide a different behavior—for example, custom layout logic.</p><p>For example, how do you build a <code>CustomButton</code> that takes a label in the constructor? Create a CustomButton that composes a <code>ElevatedButton</code> with a label, rather than by extending <code>ElevatedButton</code>:</p> <?code-excerpt "lib/custom.dart (custom-button)"?> <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">class</span><span style="color:#0468D7"> CustomButton</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</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> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> CustomButton</span><span style="color:#222222">(</span><span style="color:#BD2314">this</span><span style="color:#222222">.label, {</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"> 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"> onPressed: () {},</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(label),</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>Then use <code>CustomButton</code>, just as you'd use any other Flutter widget:</p> <?code-excerpt "lib/custom.dart (use-custom-button)"?> <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"> Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">CustomButton</span><span style="color:#222222">(</span><span style="color:#0C7064">'Hello'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="intents">Intents</h2><a class="heading-link" href="#intents" aria-label="Link to 'Intents' section">#</a></div><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-an-intent-in-flutter">What is the equivalent of an Intent in Flutter?</h3><a class="heading-link" href="#what-is-the-equivalent-of-an-intent-in-flutter" aria-label="Link to 'What is the equivalent of an Intent in Flutter?' section">#</a></div><p>In Android, there are two main use cases for <code>Intent</code>s: navigating between Activities, and communicating with components. Flutter, on the other hand, does not have the concept of intents, although you can still start intents through native integrations (using <a href="https://pub.dev/packages/android_intent">a plugin</a>).</p><p>Flutter doesn't really have a direct equivalent to activities and fragments; rather, in Flutter you navigate between screens, using a <code>Navigator</code> and <code>Route</code>s, all within the same <code>Activity</code>.</p><p>A <code>Route</code> is an abstraction for a &quot;screen&quot; or &quot;page&quot; of an app, and a <code>Navigator</code> is a widget that manages routes. A route roughly maps to an <code>Activity</code>, but it does not carry the same meaning. A navigator can push and pop routes to move from screen to screen. Navigators work like a stack on which you can <code>push()</code> new routes you want to navigate to, and from which you can <code>pop()</code> routes when you want to &quot;go back&quot;.</p><p>In Android, you declare your activities inside the app's <code>AndroidManifest.xml</code>.</p><p>In Flutter, you have a couple options to navigate between pages:</p><ul><li>Specify a <code>Map</code> of route names. (using <code>MaterialApp</code>)</li><li>Directly navigate to a route. (using <code>WidgetsApp</code>)</li></ul><p>The following example builds a Map.</p> <?code-excerpt "lib/intent.dart (map)"?> <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">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#0468D7">MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> MyAppHome</span><span style="color:#222222">(), </span><span style="color:#6E6E70">// Becomes the route named '/'.</span></span> <span class="line"><span style="color:#222222"> routes: &#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">WidgetBuilder</span><span style="color:#222222">>{</span></span> <span class="line"><span style="color:#0C7064"> '/a'</span><span style="color:#222222">: (context) => </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> MyPage</span><span style="color:#222222">(title: </span><span style="color:#0C7064">'page A'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0C7064"> '/b'</span><span style="color:#222222">: (context) => </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> MyPage</span><span style="color:#222222">(title: </span><span style="color:#0C7064">'page B'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0C7064"> '/c'</span><span style="color:#222222">: (context) => </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> MyPage</span><span style="color:#222222">(title: </span><span style="color:#0C7064">'page C'</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>Navigate to a route by <code>push</code>ing its name to the <code>Navigator</code>.</p> <?code-excerpt "lib/intent.dart (push)"?> <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">Navigator</span><span style="color:#222222">.</span><span style="color:#6200EE">of</span><span style="color:#222222">(context).</span><span style="color:#6200EE">pushNamed</span><span style="color:#222222">(</span><span style="color:#0C7064">'/b'</span><span style="color:#222222">);</span></span></code></pre></div></div><p>The other popular use-case for <code>Intent</code>s is to call external components such as a Camera or File picker. For this, you would need to create a native platform integration (or use an <a href="https://pub.dev/flutter/">existing plugin</a>).</p><p>To learn how to build a native platform integration, see <a href="/packages-and-plugins/developing-packages">developing packages and plugins</a>.</p><div class="header-wrapper"><h3 id="how-do-i-handle-incoming-intents-from-external-applications-in-flutter">How do I handle incoming intents from external applications in Flutter?</h3><a class="heading-link" href="#how-do-i-handle-incoming-intents-from-external-applications-in-flutter" aria-label="Link to 'How do I handle incoming intents from external applications in Flutter?' section">#</a></div><p>Flutter can handle incoming intents from Android by directly talking to the Android layer and requesting the data that was shared.</p><p>The following example registers a text share intent filter on the native activity that runs our Flutter code, so other apps can share text with our Flutter app.</p><p>The basic flow implies that we first handle the shared text data on the Android native side (in our <code>Activity</code>), and then wait until Flutter requests for the data to provide it using a <code>MethodChannel</code>.</p><p>First, register the intent filter for all intents in <code>AndroidManifest.xml</code>:</p><div class="code-block-wrapper language-xml"><div class="code-block-body"><span class="code-block-language" title="Language xml">xml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">activity</span></span> <span class="line"><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">name</span><span style="color:#222222">=</span><span style="color:#0C7064">".MainActivity"</span></span> <span class="line"><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">launchMode</span><span style="color:#222222">=</span><span style="color:#0C7064">"singleTop"</span></span> <span class="line"><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">theme</span><span style="color:#222222">=</span><span style="color:#0C7064">"@style/LaunchTheme"</span></span> <span class="line"><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">configChanges</span><span style="color:#222222">=</span><span style="color:#0C7064">"orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"</span></span> <span class="line"><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">hardwareAccelerated</span><span style="color:#222222">=</span><span style="color:#0C7064">"true"</span></span> <span class="line"><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">windowSoftInputMode</span><span style="color:#222222">=</span><span style="color:#0C7064">"adjustResize"</span><span style="color:#222222">></span></span> <span class="line"><span style="color:#6E6E70"> &#x3C;!-- ... --></span></span> <span class="line"><span style="color:#222222"> &#x3C;</span><span style="color:#0468D7">intent-filter</span><span style="color:#222222">></span></span> <span class="line"><span style="color:#222222"> &#x3C;</span><span style="color:#0468D7">action</span><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">name</span><span style="color:#222222">=</span><span style="color:#0C7064">"android.intent.action.SEND"</span><span style="color:#222222"> /></span></span> <span class="line"><span style="color:#222222"> &#x3C;</span><span style="color:#0468D7">category</span><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">name</span><span style="color:#222222">=</span><span style="color:#0C7064">"android.intent.category.DEFAULT"</span><span style="color:#222222"> /></span></span> <span class="line"><span style="color:#222222"> &#x3C;</span><span style="color:#0468D7">data</span><span style="color:#6200EE"> android</span><span style="color:#222222">:</span><span style="color:#6200EE">mimeType</span><span style="color:#222222">=</span><span style="color:#0C7064">"text/plain"</span><span style="color:#222222"> /></span></span> <span class="line"><span style="color:#222222"> &#x3C;/</span><span style="color:#0468D7">intent-filter</span><span style="color:#222222">></span></span> <span class="line"><span style="color:#222222">&#x3C;/</span><span style="color:#0468D7">activity</span><span style="color:#222222">></span></span></code></pre></div></div><p>Then in <code>MainActivity</code>, handle the intent, extract the text that was shared from the intent, and hold onto it. When Flutter is ready to process, it requests the data using a platform channel, and it's sent across from the native side:</p><div class="code-block-wrapper language-java"><div class="code-block-body"><span class="code-block-language" title="Language java">java</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">package</span><span style="color:#222222"> com.example.shared;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> android</span><span style="color:#222222">.</span><span style="color:#BD2314">content</span><span style="color:#222222">.</span><span style="color:#BD2314">Intent</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> android</span><span style="color:#222222">.</span><span style="color:#BD2314">os</span><span style="color:#222222">.</span><span style="color:#BD2314">Bundle</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> androidx</span><span style="color:#222222">.</span><span style="color:#BD2314">annotation</span><span style="color:#222222">.</span><span style="color:#BD2314">NonNull</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> io</span><span style="color:#222222">.</span><span style="color:#BD2314">flutter</span><span style="color:#222222">.</span><span style="color:#BD2314">plugin</span><span style="color:#222222">.</span><span style="color:#BD2314">common</span><span style="color:#222222">.</span><span style="color:#BD2314">MethodChannel</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> io</span><span style="color:#222222">.</span><span style="color:#BD2314">flutter</span><span style="color:#222222">.</span><span style="color:#BD2314">embedding</span><span style="color:#222222">.</span><span style="color:#BD2314">android</span><span style="color:#222222">.</span><span style="color:#BD2314">FlutterActivity</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> io</span><span style="color:#222222">.</span><span style="color:#BD2314">flutter</span><span style="color:#222222">.</span><span style="color:#BD2314">embedding</span><span style="color:#222222">.</span><span style="color:#BD2314">engine</span><span style="color:#222222">.</span><span style="color:#BD2314">FlutterEngine</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#BD2314"> io</span><span style="color:#222222">.</span><span style="color:#BD2314">flutter</span><span style="color:#222222">.</span><span style="color:#BD2314">plugins</span><span style="color:#222222">.</span><span style="color:#BD2314">GeneratedPluginRegistrant</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">public</span><span style="color:#BD2314"> class</span><span style="color:#0468D7"> MainActivity</span><span style="color:#BD2314"> extends</span><span style="color:#222222"> FlutterActivity {</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> private</span><span style="color:#BD2314"> String</span><span style="color:#222222"> sharedText;</span></span> <span class="line"><span style="color:#BD2314"> private</span><span style="color:#BD2314"> static</span><span style="color:#BD2314"> final</span><span style="color:#BD2314"> String</span><span style="color:#222222"> CHANNEL = </span><span style="color:#0C7064">"app.channel.shared.data"</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#222222"> @</span><span style="color:#BD2314">Override</span></span> <span class="line"><span style="color:#BD2314"> protected</span><span style="color:#BD2314"> void</span><span style="color:#6200EE"> onCreate</span><span style="color:#222222">(</span><span style="color:#BD2314">Bundle</span><span style="color:#222222"> savedInstanceState) {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">onCreate</span><span style="color:#222222">(savedInstanceState);</span></span> <span class="line"><span style="color:#BD2314"> Intent</span><span style="color:#222222"> intent = </span><span style="color:#6200EE">getIntent</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#BD2314"> String</span><span style="color:#222222"> action = intent.</span><span style="color:#6200EE">getAction</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#BD2314"> String</span><span style="color:#222222"> type = intent.</span><span style="color:#6200EE">getType</span><span style="color:#222222">();</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (Intent.ACTION_SEND.</span><span style="color:#6200EE">equals</span><span style="color:#222222">(action) &#x26;&#x26; type != </span><span style="color:#0C7064">null</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (</span><span style="color:#0C7064">"text/plain"</span><span style="color:#222222">.</span><span style="color:#6200EE">equals</span><span style="color:#222222">(type)) {</span></span> <span class="line"><span style="color:#6200EE"> handleSendText</span><span style="color:#222222">(intent); </span><span style="color:#6E6E70">// Handle text being sent</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> <span class="line"><span style="color:#222222"> @</span><span style="color:#BD2314">Override</span></span> <span class="line"><span style="color:#BD2314"> public</span><span style="color:#BD2314"> void</span><span style="color:#6200EE"> configureFlutterEngine</span><span style="color:#222222">(@</span><span style="color:#BD2314">NonNull</span><span style="color:#BD2314"> FlutterEngine</span><span style="color:#222222"> flutterEngine) {</span></span> <span class="line"><span style="color:#222222"> GeneratedPluginRegistrant.</span><span style="color:#6200EE">registerWith</span><span style="color:#222222">(flutterEngine);</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> new</span><span style="color:#6200EE"> MethodChannel</span><span style="color:#222222">(flutterEngine.</span><span style="color:#6200EE">getDartExecutor</span><span style="color:#222222">().</span><span style="color:#6200EE">getBinaryMessenger</span><span style="color:#222222">(), CHANNEL)</span></span> <span class="line"><span style="color:#222222"> .</span><span style="color:#6200EE">setMethodCallHandler</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> (call, result) </span><span style="color:#BD2314">-></span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (call.method.</span><span style="color:#6200EE">contentEquals</span><span style="color:#222222">(</span><span style="color:#0C7064">"getSharedText"</span><span style="color:#222222">)) {</span></span> <span class="line"><span style="color:#222222"> result.</span><span style="color:#6200EE">success</span><span style="color:#222222">(sharedText);</span></span> <span class="line"><span style="color:#222222"> sharedText = </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:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> handleSendText</span><span style="color:#222222">(</span><span style="color:#BD2314">Intent</span><span style="color:#222222"> intent) {</span></span> <span class="line"><span style="color:#222222"> sharedText = intent.</span><span style="color:#6200EE">getStringExtra</span><span style="color:#222222">(Intent.EXTRA_TEXT);</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>Finally, request the data from the Flutter side when the widget is rendered:</p> <?code-excerpt "lib/request_data.dart"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/services.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</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:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample Shared App Handler'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#BD2314"> static</span><span style="color:#BD2314"> const</span><span style="color:#222222"> platform = </span><span style="color:#0468D7">MethodChannel</span><span style="color:#222222">(</span><span style="color:#0C7064">'app.channel.shared.data'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> dataShared = </span><span style="color:#0C7064">'No data'</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:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#6200EE"> getSharedText</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"> @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"> Scaffold</span><span style="color:#222222">(body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(dataShared)));</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">getSharedText</span><span style="color:#222222">() </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"> sharedData = </span><span style="color:#BD2314">await</span><span style="color:#222222"> platform.</span><span style="color:#6200EE">invokeMethod</span><span style="color:#222222">(</span><span style="color:#0C7064">'getSharedText'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (sharedData != </span><span style="color:#0C7064">null</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> dataShared = sharedData;</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-startactivityforresult">What is the equivalent of startActivityForResult()?</h3><a class="heading-link" href="#what-is-the-equivalent-of-startactivityforresult" aria-label="Link to 'What is the equivalent of startActivityForResult()?' section">#</a></div><p>The <code>Navigator</code> class handles routing in Flutter and is used to get a result back from a route that you have pushed on the stack. This is done by <code>await</code>ing on the <code>Future</code> returned by <code>push()</code>.</p><p>For example, to start a location route that lets the user select their location, you could do the following:</p> <?code-excerpt "lib/intent.dart (push-await)"?> <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">Object</span><span style="color:#222222">? coordinates = </span><span style="color:#BD2314">await</span><span style="color:#0468D7"> Navigator</span><span style="color:#222222">.</span><span style="color:#6200EE">of</span><span style="color:#222222">(context).</span><span style="color:#6200EE">pushNamed</span><span style="color:#222222">(</span><span style="color:#0C7064">'/location'</span><span style="color:#222222">);</span></span></code></pre></div></div><p>And then, inside your location route, once the user has selected their location you can <code>pop</code> the stack with the result:</p> <?code-excerpt "lib/intent.dart (pop)"?> <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">Navigator</span><span style="color:#222222">.</span><span style="color:#6200EE">of</span><span style="color:#222222">(context).</span><span style="color:#6200EE">pop</span><span style="color:#222222">({</span><span style="color:#0C7064">'lat'</span><span style="color:#222222">: </span><span style="color:#0C7064">43.821757</span><span style="color:#222222">, </span><span style="color:#0C7064">'long'</span><span style="color:#222222">: -</span><span style="color:#0C7064">79.226392</span><span style="color:#222222">});</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="async-ui">Async UI</h2><a class="heading-link" href="#async-ui" aria-label="Link to 'Async UI' section">#</a></div><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-runonuithread-in-flutter">What is the equivalent of runOnUiThread() in Flutter?</h3><a class="heading-link" href="#what-is-the-equivalent-of-runonuithread-in-flutter" aria-label="Link to 'What is the equivalent of runOnUiThread() in Flutter?' section">#</a></div><p>Dart has a single-threaded execution model, with support for <code>Isolate</code>s (a way to run Dart code on another thread), an event loop, and asynchronous programming. Unless you spawn an <code>Isolate</code>, your Dart code runs in the main UI thread and is driven by an event loop. Flutter's event loop is equivalent to Android's main <code>Looper</code>—that is, the <code>Looper</code> that is attached to the main thread.</p><p>Dart's single-threaded model doesn't mean you need to run everything as a blocking operation that causes the UI to freeze. Unlike Android, which requires you to keep the main thread free at all times, in Flutter, use the asynchronous facilities that the Dart language provides, such as <code>async</code>/<code>await</code>, to perform asynchronous work. You might be familiar with the <code>async</code>/<code>await</code> paradigm if you've used it in C#, Javascript, or if you have used Kotlin's coroutines.</p><p>For example, you can run network code without causing the UI to hang by using <code>async</code>/<code>await</code> and letting Dart do the heavy lifting:</p> <?code-excerpt "lib/async.dart (load-data)"?> <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">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </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"> dataURL = </span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(</span><span style="color:#0C7064">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(dataURL);</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> widgets = </span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body);</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>Once the <code>await</code>ed network call is done, update the UI by calling <code>setState()</code>, which triggers a rebuild of the widget subtree and updates the data.</p><p>The following example loads data asynchronously and displays it in a <code>ListView</code>:</p> <?code-excerpt "lib/async.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:convert'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:http/http.dart'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> http;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222"> widgets = [];</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#6200EE"> loadData</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"> @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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </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: widgets.length,</span></span> <span class="line"><span style="color:#222222"> itemBuilder: (context, position) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(position);</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> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">"Row </span><span style="color:#0C7064">${</span><span style="color:#222222">widgets</span><span style="color:#0C7064">[</span><span style="color:#222222">i</span><span style="color:#0C7064">][</span><span style="color:#0C7064">"title"</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> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </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"> dataURL = </span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(</span><span style="color:#0C7064">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(dataURL);</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> widgets = </span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body);</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>Refer to the next section for more information on doing work in the background, and how Flutter differs from Android.</p><div class="header-wrapper"><h3 id="how-do-you-move-work-to-a-background-thread">How do you move work to a background thread?</h3><a class="heading-link" href="#how-do-you-move-work-to-a-background-thread" aria-label="Link to 'How do you move work to a background thread?' section">#</a></div><p>In Android, when you want to access a network resource you would typically move to a background thread and do the work, as to not block the main thread, and avoid ANRs. For example, you might be using an <code>AsyncTask</code>, a <code>LiveData</code>, an <code>IntentService</code>, a <code>JobScheduler</code> job, or an RxJava pipeline with a scheduler that works on background threads.</p><p>Since Flutter is single threaded and runs an event loop (like Node.js), you don't have to worry about thread management or spawning background threads. If you're doing I/O-bound work, such as disk access or a network call, then you can safely use <code>async</code>/<code>await</code> and you're all set. If, on the other hand, you need to do computationally intensive work that keeps the CPU busy, you want to move it to an <code>Isolate</code> to avoid blocking the event loop, like you would keep <em>any</em> sort of work out of the main thread in Android.</p><p>For I/O-bound work, declare the function as an <code>async</code> function, and <code>await</code> on long-running tasks inside the function:</p> <?code-excerpt "lib/async.dart (load-data)"?> <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">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </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"> dataURL = </span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(</span><span style="color:#0C7064">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(dataURL);</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> widgets = </span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body);</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>This is how you would typically do network or database calls, which are both I/O operations.</p><p>On Android, when you extend <code>AsyncTask</code>, you typically override 3 methods, <code>onPreExecute()</code>, <code>doInBackground()</code> and <code>onPostExecute()</code>. There is no equivalent in Flutter, since you <code>await</code> on a long-running function, and Dart's event loop takes care of the rest.</p><p>However, there are times when you might be processing a large amount of data and your UI hangs. In Flutter, use <code>Isolate</code>s to take advantage of multiple CPU cores to do long-running or computationally intensive tasks.</p><p>Isolates are separate execution threads that do not share any memory with the main execution memory heap. This means you can't access variables from the main thread, or update your UI by calling <code>setState()</code>. Unlike Android threads, Isolates are true to their name, and cannot share memory (in the form of static fields, for example).</p><p>The following example shows, in a simple isolate, how to share data back to the main thread to update the UI.</p> <?code-excerpt "lib/isolates.dart (load-data)"?> <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">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#0468D7"> ReceivePort</span><span style="color:#222222"> receivePort = </span><span style="color:#0468D7">ReceivePort</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#BD2314"> await</span><span style="color:#0468D7"> Isolate</span><span style="color:#222222">.</span><span style="color:#6200EE">spawn</span><span style="color:#222222">(dataLoader, receivePort.sendPort);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // The 'echo' isolate sends its SendPort as the first message.</span></span> <span class="line"><span style="color:#0468D7"> SendPort</span><span style="color:#222222"> sendPort = </span><span style="color:#BD2314">await</span><span style="color:#222222"> receivePort.first;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#222222"> msg = </span><span style="color:#BD2314">await</span><span style="color:#6200EE"> sendReceive</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> sendPort,</span></span> <span class="line"><span style="color:#0C7064"> 'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> ) </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Object</span><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"> widgets = msg;</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:#6E6E70">// The entry point for the isolate.</span></span> <span class="line"><span style="color:#BD2314">static</span><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">dataLoader</span><span style="color:#222222">(</span><span style="color:#0468D7">SendPort</span><span style="color:#222222"> sendPort) </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> // Open the ReceivePort for incoming messages.</span></span> <span class="line"><span style="color:#0468D7"> ReceivePort</span><span style="color:#222222"> port = </span><span style="color:#0468D7">ReceivePort</span><span style="color:#222222">();</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // Notify any other isolates what port this isolate listens to.</span></span> <span class="line"><span style="color:#222222"> sendPort.</span><span style="color:#6200EE">send</span><span style="color:#222222">(port.sendPort);</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> await</span><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#BD2314">var</span><span style="color:#222222"> msg </span><span style="color:#BD2314">in</span><span style="color:#222222"> port) {</span></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> data = msg[</span><span style="color:#0C7064">0</span><span style="color:#222222">];</span></span> <span class="line"><span style="color:#0468D7"> SendPort</span><span style="color:#222222"> replyTo = msg[</span><span style="color:#0C7064">1</span><span style="color:#222222">];</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> dataURL = data;</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(</span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(dataURL));</span></span> <span class="line"><span style="color:#6E6E70"> // Lots of JSON to parse</span></span> <span class="line"><span style="color:#222222"> replyTo.</span><span style="color:#6200EE">send</span><span style="color:#222222">(</span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body));</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:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Object</span><span style="color:#222222">?> </span><span style="color:#6200EE">sendReceive</span><span style="color:#222222">(</span><span style="color:#0468D7">SendPort</span><span style="color:#222222"> port, </span><span style="color:#0468D7">Object</span><span style="color:#222222">? msg) {</span></span> <span class="line"><span style="color:#0468D7"> ReceivePort</span><span style="color:#222222"> response = </span><span style="color:#0468D7">ReceivePort</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> port.</span><span style="color:#6200EE">send</span><span style="color:#222222">([msg, response.sendPort]);</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#222222"> response.first;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Here, <code>dataLoader()</code> is the <code>Isolate</code> that runs in its own separate execution thread. In the isolate you can perform more CPU intensive processing (parsing a big JSON, for example), or perform computationally intensive math, such as encryption or signal processing.</p><p>You can run the full example below:</p> <?code-excerpt "lib/isolates.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:async'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'dart:convert'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'dart:isolate'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:http/http.dart'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> http;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</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"> 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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222"> widgets = [];</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#6200EE"> loadData</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:#0468D7"> Widget</span><span style="color:#6200EE"> getBody</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#222222"> showLoadingDialog = widgets.isEmpty;</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (showLoadingDialog) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getProgressDialog</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#BD2314">else</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getListView</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> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> getProgressDialog</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#BD2314"> const</span><span style="color:#0468D7"> Center</span><span style="color:#222222">(child: </span><span style="color:#0468D7">CircularProgressIndicator</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"> @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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#6200EE">getBody</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> <span class="line"><span style="color:#0468D7"> ListView</span><span style="color:#6200EE"> getListView</span><span style="color:#222222">() {</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: widgets.length,</span></span> <span class="line"><span style="color:#222222"> itemBuilder: (context, position) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(position);</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> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">"Row </span><span style="color:#0C7064">${</span><span style="color:#222222">widgets</span><span style="color:#0C7064">[</span><span style="color:#222222">i</span><span style="color:#0C7064">][</span><span style="color:#0C7064">"title"</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> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#0468D7"> ReceivePort</span><span style="color:#222222"> receivePort = </span><span style="color:#0468D7">ReceivePort</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#BD2314"> await</span><span style="color:#0468D7"> Isolate</span><span style="color:#222222">.</span><span style="color:#6200EE">spawn</span><span style="color:#222222">(dataLoader, receivePort.sendPort);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // The 'echo' isolate sends its SendPort as the first message.</span></span> <span class="line"><span style="color:#0468D7"> SendPort</span><span style="color:#222222"> sendPort = </span><span style="color:#BD2314">await</span><span style="color:#222222"> receivePort.first;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#222222"> msg = </span><span style="color:#BD2314">await</span><span style="color:#6200EE"> sendReceive</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> sendPort,</span></span> <span class="line"><span style="color:#0C7064"> 'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> ) </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Object</span><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"> widgets = msg;</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:#6E6E70"> // The entry point for the isolate.</span></span> <span class="line"><span style="color:#BD2314"> static</span><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">dataLoader</span><span style="color:#222222">(</span><span style="color:#0468D7">SendPort</span><span style="color:#222222"> sendPort) </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> // Open the ReceivePort for incoming messages.</span></span> <span class="line"><span style="color:#0468D7"> ReceivePort</span><span style="color:#222222"> port = </span><span style="color:#0468D7">ReceivePort</span><span style="color:#222222">();</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // Notify any other isolates what port this isolate listens to.</span></span> <span class="line"><span style="color:#222222"> sendPort.</span><span style="color:#6200EE">send</span><span style="color:#222222">(port.sendPort);</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> await</span><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#BD2314">var</span><span style="color:#222222"> msg </span><span style="color:#BD2314">in</span><span style="color:#222222"> port) {</span></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> data = msg[</span><span style="color:#0C7064">0</span><span style="color:#222222">];</span></span> <span class="line"><span style="color:#0468D7"> SendPort</span><span style="color:#222222"> replyTo = msg[</span><span style="color:#0C7064">1</span><span style="color:#222222">];</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> dataURL = data;</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(</span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(dataURL));</span></span> <span class="line"><span style="color:#6E6E70"> // Lots of JSON to parse</span></span> <span class="line"><span style="color:#222222"> replyTo.</span><span style="color:#6200EE">send</span><span style="color:#222222">(</span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body));</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:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Object</span><span style="color:#222222">?> </span><span style="color:#6200EE">sendReceive</span><span style="color:#222222">(</span><span style="color:#0468D7">SendPort</span><span style="color:#222222"> port, </span><span style="color:#0468D7">Object</span><span style="color:#222222">? msg) {</span></span> <span class="line"><span style="color:#0468D7"> ReceivePort</span><span style="color:#222222"> response = </span><span style="color:#0468D7">ReceivePort</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> port.</span><span style="color:#6200EE">send</span><span style="color:#222222">([msg, response.sendPort]);</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#222222"> response.first;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-okhttp-on-flutter">What is the equivalent of OkHttp on Flutter?</h3><a class="heading-link" href="#what-is-the-equivalent-of-okhttp-on-flutter" aria-label="Link to 'What is the equivalent of OkHttp on Flutter?' section">#</a></div><p>Making a network call in Flutter is easy when you use the popular <a href="https://pub.dev/packages/http"><code>http</code> package</a>.</p><p>While the http package doesn't have every feature found in OkHttp, it abstracts away much of the networking that you would normally implement yourself, making it a simple way to make network calls.</p><p>To add the <code>http</code> package as a dependency, run <code>flutter pub add</code>:</p><div class="code-block-wrapper language-console"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222" class="undefined terminal-command">flutter pub add http</span></span></code></pre></div></div><p>To make a network call, call <code>await</code> on the <code>async</code> function <code>http.get()</code>:</p> <?code-excerpt "lib/network.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:developer'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> developer;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:http/http.dart'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> http;</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </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"> dataURL = </span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(</span><span style="color:#0C7064">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(dataURL);</span></span> <span class="line"><span style="color:#222222"> developer.</span><span style="color:#6200EE">log</span><span style="color:#222222">(response.body);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-show-the-progress-for-a-long-running-task">How do I show the progress for a long-running task?</h3><a class="heading-link" href="#how-do-i-show-the-progress-for-a-long-running-task" aria-label="Link to 'How do I show the progress for a long-running task?' section">#</a></div><p>In Android you would typically show a <code>ProgressBar</code> view in your UI while executing a long-running task on a background thread.</p><p>In Flutter, use a <code>ProgressIndicator</code> widget. Show the progress programmatically by controlling when it's rendered through a boolean flag. Tell Flutter to update its state before your long-running task starts, and hide it after it ends.</p><p>In the following example, the build function is separated into three different functions. If <code>showLoadingDialog</code> is <code>true</code> (when <code>widgets.isEmpty</code>), then render the <code>ProgressIndicator</code>. Otherwise, render the <code>ListView</code> with the data returned from a network call.</p> <?code-excerpt "lib/progress.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:convert'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:http/http.dart'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> http;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</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"> 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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222"> widgets = [];</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#6200EE"> loadData</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:#0468D7"> Widget</span><span style="color:#6200EE"> getBody</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#222222"> showLoadingDialog = widgets.isEmpty;</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (showLoadingDialog) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getProgressDialog</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#BD2314">else</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getListView</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> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> getProgressDialog</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#BD2314"> const</span><span style="color:#0468D7"> Center</span><span style="color:#222222">(child: </span><span style="color:#0468D7">CircularProgressIndicator</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"> @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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#6200EE">getBody</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> <span class="line"><span style="color:#0468D7"> ListView</span><span style="color:#6200EE"> getListView</span><span style="color:#222222">() {</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: widgets.length,</span></span> <span class="line"><span style="color:#222222"> itemBuilder: (context, position) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(position);</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> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">"Row </span><span style="color:#0C7064">${</span><span style="color:#222222">widgets</span><span style="color:#0C7064">[</span><span style="color:#222222">i</span><span style="color:#0C7064">][</span><span style="color:#0C7064">"title"</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> <span class="line"><span style="color:#0468D7"> Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">loadData</span><span style="color:#222222">() </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"> dataURL = </span><span style="color:#0468D7">Uri</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(</span><span style="color:#0C7064">'https://jsonplaceholder.typicode.com/posts'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> http.</span><span style="color:#0468D7">Response</span><span style="color:#222222"> response = </span><span style="color:#BD2314">await</span><span style="color:#222222"> http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(dataURL);</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> widgets = </span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body);</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="project-structure-resources">Project structure &amp; resources</h2><a class="heading-link" href="#project-structure-resources" aria-label="Link to 'Project structure &amp; resources' section">#</a></div><div class="header-wrapper"><h3 id="where-do-i-store-my-resolution-dependent-image-files">Where do I store my resolution-dependent image files?</h3><a class="heading-link" href="#where-do-i-store-my-resolution-dependent-image-files" aria-label="Link to 'Where do I store my resolution-dependent image files?' section">#</a></div><p>While Android treats resources and assets as distinct items, Flutter apps have only assets. All resources that would live in the <code>res/drawable-*</code> folders on Android, are placed in an assets folder for Flutter.</p><p>Flutter follows a simple density-based format like iOS. Assets might be <code>1.0x</code>, <code>2.0x</code>, <code>3.0x</code>, or any other multiplier. Flutter doesn't have <code>dp</code>s but there are logical pixels, which are basically the same as device-independent pixels. Flutter's <a href="https://api.flutter.dev/flutter/dart-ui/FlutterView/devicePixelRatio.html"><code>devicePixelRatio</code></a> expresses the ratio of physical pixels in a single logical pixel.</p><p>The equivalent to Android's density buckets are:</p><div class="table-wrapper"><table><thead><tr><th>Android density qualifier</th><th>Flutter pixel ratio</th></tr></thead><tbody><tr><td><code>ldpi</code></td><td><code>0.75x</code></td></tr><tr><td><code>mdpi</code></td><td><code>1.0x</code></td></tr><tr><td><code>hdpi</code></td><td><code>1.5x</code></td></tr><tr><td><code>xhdpi</code></td><td><code>2.0x</code></td></tr><tr><td><code>xxhdpi</code></td><td><code>3.0x</code></td></tr><tr><td><code>xxxhdpi</code></td><td><code>4.0x</code></td></tr></tbody></table></div><p>Assets are located in any arbitrary folder—Flutter has no predefined folder structure. You declare the assets (with location) in the <code>pubspec.yaml</code> file, and Flutter picks them up.</p><p>Assets stored in the native asset folder are accessed on the native side using Android's <code>AssetManager</code>:</p><div class="code-block-wrapper language-kotlin"><div class="code-block-body"><span class="code-block-language" title="Language kotlin">kotlin</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#BD2314">val</span><span style="color:#222222"> flutterAssetStream = assetManager.</span><span style="color:#6200EE">open</span><span style="color:#222222">(</span><span style="color:#0C7064">"flutter_assets/assets/my_flutter_asset.png"</span><span style="color:#222222">)</span></span></code></pre></div></div><p>Flutter can't access native resources or assets.</p><p>To add a new image asset called <code>my_icon.png</code> to our Flutter project, for example, and deciding that it should live in a folder we arbitrarily called <code>images</code>, you would put the base image (1.0x) in the <code>images</code> folder, and all the other variants in sub-folders called with the appropriate ratio multiplier:</p><div class="code-block-wrapper language-plaintext"><div class="code-block-body"><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span>images/my_icon.png // Base: 1.0x image</span></span> <span class="line"><span>images/2.0x/my_icon.png // 2.0x image</span></span> <span class="line"><span>images/3.0x/my_icon.png // 3.0x image</span></span></code></pre></div></div><p>Next, you'll need to declare these images in your <code>pubspec.yaml</code> file:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">assets</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#222222"> - </span><span style="color:#0C7064">images/my_icon.jpeg</span></span></code></pre></div></div><p>You can then access your images using <code>AssetImage</code>:</p> <?code-excerpt "lib/images.dart (asset-image)"?> <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">AssetImage</span><span style="color:#222222">(</span><span style="color:#0C7064">'images/my_icon.jpeg'</span><span style="color:#222222">)</span></span></code></pre></div></div><p>or directly in an <code>Image</code> widget:</p> <?code-excerpt "lib/images.dart (image-asset)"?> <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"> Image</span><span style="color:#222222">.</span><span style="color:#6200EE">asset</span><span style="color:#222222">(</span><span style="color:#0C7064">'images/my_image.png'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="where-do-i-store-strings-how-do-i-handle-localization">Where do I store strings? How do I handle localization?</h3><a class="heading-link" href="#where-do-i-store-strings-how-do-i-handle-localization" aria-label="Link to 'Where do I store strings? How do I handle localization?' section">#</a></div><p>Flutter currently doesn't have a dedicated resources-like system for strings. The best and recommended practice is to hold your strings in a <code>.arb</code> file as key-value pairs For example:</p> <?code-excerpt "lib/arb_examples.arb"?> <div class="code-block-wrapper language-json"><div class="code-block-body"><span class="code-block-language" title="Language json">json</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">{</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">@@locale</span><span style="color:#222222">"</span><span style="color:#222222">: </span><span style="color:#0C7064">"en"</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">hello</span><span style="color:#222222">"</span><span style="color:#222222">:</span><span style="color:#0C7064">"Hello {userName}"</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">@hello</span><span style="color:#222222">"</span><span style="color:#222222">:{</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">description</span><span style="color:#222222">"</span><span style="color:#222222">:</span><span style="color:#0C7064">"A message with a single parameter"</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">placeholders</span><span style="color:#222222">"</span><span style="color:#222222">:{</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">userName</span><span style="color:#222222">"</span><span style="color:#222222">:{</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">type</span><span style="color:#222222">"</span><span style="color:#222222">:</span><span style="color:#0C7064">"String"</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> "</span><span style="color:#0468D7">example</span><span style="color:#222222">"</span><span style="color:#222222">:</span><span style="color:#0C7064">"Bob"</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>Then in your code, you can access your strings as such:</p> <?code-excerpt "lib/localization_examples.dart (access-string)"?> <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">Text</span><span style="color:#222222">(</span><span style="color:#0468D7">AppLocalizations</span><span style="color:#222222">.</span><span style="color:#6200EE">of</span><span style="color:#222222">(context)!.</span><span style="color:#6200EE">hello</span><span style="color:#222222">(</span><span style="color:#0C7064">'John'</span><span style="color:#222222">));</span></span></code></pre></div></div><p>Flutter has basic support for accessibility on Android, though this feature is a work in progress.</p><p>See <a href="/ui/accessibility-and-internationalization/internationalization">Internationalizing Flutter apps</a> for more information on this.</p><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-a-gradle-file-how-do-i-add-dependencies">What is the equivalent of a Gradle file? How do I add dependencies?</h3><a class="heading-link" href="#what-is-the-equivalent-of-a-gradle-file-how-do-i-add-dependencies" aria-label="Link to 'What is the equivalent of a Gradle file? How do I add dependencies?' section">#</a></div><p>In Android, you add dependencies by adding to your Gradle build script. Flutter uses Dart's own build system, and the Pub package manager. The tools delegate the building of the native Android and iOS wrapper apps to the respective build systems.</p><p>While there are Gradle files under the <code>android</code> folder in your Flutter project, only use these if you are adding native dependencies needed for per-platform integration. In general, use <code>pubspec.yaml</code> to declare external dependencies to use in Flutter. A good place to find Flutter packages is <a href="https://pub.dev/flutter/packages/">pub.dev</a>.</p><div class="header-wrapper"><h2 id="activities-and-fragments">Activities and fragments</h2><a class="heading-link" href="#activities-and-fragments" aria-label="Link to 'Activities and fragments' section">#</a></div><div class="header-wrapper"><h3 id="what-are-the-equivalent-of-activities-and-fragments-in-flutter">What are the equivalent of activities and fragments in Flutter?</h3><a class="heading-link" href="#what-are-the-equivalent-of-activities-and-fragments-in-flutter" aria-label="Link to 'What are the equivalent of activities and fragments in Flutter?' section">#</a></div><p>In Android, an <code>Activity</code> represents a single focused thing the user can do. A <code>Fragment</code> represents a behavior or a portion of user interface. Fragments are a way to modularize your code, compose sophisticated user interfaces for larger screens, and help scale your application UI. In Flutter, both of these concepts fall under the umbrella of <code>Widget</code>s.</p><p>To learn more about the UI for building Activities and Fragments, see the community-contributed Medium article, <a href="https://blog.usejournal.com/flutter-for-android-developers-how-to-design-activity-ui-in-flutter-4bf7b0de1e48">Flutter for Android Developers: How to design Activity UI in Flutter</a>.</p><p>As mentioned in the <a href="#what-is-the-equivalent-of-an-intent-in-flutter">Intents</a> section, screens in Flutter are represented by <code>Widget</code>s since everything is a widget in Flutter. Use a <code>Navigator</code> to move between different <code>Route</code>s that represent different screens or pages, or perhaps different states or renderings of the same data.</p><div class="header-wrapper"><h3 id="how-do-i-listen-to-android-activity-lifecycle-events">How do I listen to Android activity lifecycle events?</h3><a class="heading-link" href="#how-do-i-listen-to-android-activity-lifecycle-events" aria-label="Link to 'How do I listen to Android activity lifecycle events?' section">#</a></div><p>In Android, you can override methods from the <code>Activity</code> to capture lifecycle methods for the activity itself, or register <code>ActivityLifecycleCallbacks</code> on the <code>Application</code>. In Flutter, you have neither concept, but you can instead listen to lifecycle events by hooking into the <code>WidgetsBinding</code> observer and listening to the <code>didChangeAppLifecycleState()</code> change event.</p><p>The observable lifecycle events are:</p><ul><li><code>detached</code> — The application is still hosted on a flutter engine but is detached from any host views.</li><li><code>inactive</code> — The application is in an inactive state and is not receiving user input.</li><li><code>paused</code> — The application is not currently visible to the user, not responding to user input, and running in the background. This is equivalent to <code>onPause()</code> in Android.</li><li><code>resumed</code> — The application is visible and responding to user input. This is equivalent to <code>onPostResume()</code> in Android.</li></ul><p>For more details on the meaning of these states, see the <a href="https://api.flutter.dev/flutter/dart-ui/AppLifecycleState.html"><code>AppLifecycleStatus</code> documentation</a>.</p><p>As you might have noticed, only a small minority of the Activity lifecycle events are available; while <code>FlutterActivity</code> does capture almost all the activity lifecycle events internally and send them over to the Flutter engine, they're mostly shielded away from you. Flutter takes care of starting and stopping the engine for you, and there is little reason for needing to observe the activity lifecycle on the Flutter side in most cases. If you need to observe the lifecycle to acquire or release any native resources, you should likely be doing it from the native side, at any rate.</p><p>Here's an example of how to observe the lifecycle status of the containing activity:</p> <?code-excerpt "lib/lifecycle.dart"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/widgets.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> LifecycleWatcher</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"> LifecycleWatcher</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">&#x3C;</span><span style="color:#0468D7">LifecycleWatcher</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_LifecycleWatcherState</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"> _LifecycleWatcherState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">LifecycleWatcher</span><span style="color:#222222">></span></span> <span class="line"><span style="color:#BD2314"> with</span><span style="color:#0468D7"> WidgetsBindingObserver</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#0468D7"> AppLifecycleState</span><span style="color:#222222">? _lastLifecycleState;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#0468D7"> WidgetsBinding</span><span style="color:#222222">.instance.</span><span style="color:#6200EE">addObserver</span><span style="color:#222222">(</span><span style="color:#BD2314">this</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"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> dispose</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> WidgetsBinding</span><span style="color:#222222">.instance.</span><span style="color:#6200EE">removeObserver</span><span style="color:#222222">(</span><span style="color:#BD2314">this</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">dispose</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"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> didChangeAppLifecycleState</span><span style="color:#222222">(</span><span style="color:#0468D7">AppLifecycleState</span><span style="color:#222222"> state) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> _lastLifecycleState = state;</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"> if</span><span style="color:#222222"> (_lastLifecycleState == </span><span style="color:#0C7064">null</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#BD2314"> const</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#0C7064"> 'This widget has not observed any lifecycle changes.'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> textDirection: </span><span style="color:#0468D7">TextDirection</span><span style="color:#222222">.ltr,</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"> return</span><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#0C7064"> 'The most recent lifecycle state this widget observed was: </span><span style="color:#0C7064">$</span><span style="color:#222222">_lastLifecycleState</span><span style="color:#0C7064">.'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> textDirection: </span><span style="color:#0468D7">TextDirection</span><span style="color:#222222">.ltr,</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> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Center</span><span style="color:#222222">(child: </span><span style="color:#0468D7">LifecycleWatcher</span><span style="color:#222222">()));</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="layouts">Layouts</h2><a class="heading-link" href="#layouts" aria-label="Link to 'Layouts' section">#</a></div><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-a-linearlayout">What is the equivalent of a LinearLayout?</h3><a class="heading-link" href="#what-is-the-equivalent-of-a-linearlayout" aria-label="Link to 'What is the equivalent of a LinearLayout?' section">#</a></div><p>In Android, a LinearLayout is used to lay your widgets out linearly—either horizontally or vertically. In Flutter, use the Row or Column widgets to achieve the same result.</p><p>If you notice the two code samples are identical with the exception of the &quot;Row&quot; and &quot;Column&quot; widget. The children are the same and this feature can be exploited to develop rich layouts that can change overtime with the same children.</p> <?code-excerpt "lib/layout.dart (row)"?> <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"> Row</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> mainAxisAlignment: </span><span style="color:#0468D7">MainAxisAlignment</span><span style="color:#222222">.center,</span></span> <span class="line"><span style="color:#222222"> children: &#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">>[</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row One'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row Two'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row Three'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row Four'</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><?code-excerpt "lib/layout.dart (column)"?> <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"> Column</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> mainAxisAlignment: </span><span style="color:#0468D7">MainAxisAlignment</span><span style="color:#222222">.center,</span></span> <span class="line"><span style="color:#222222"> children: &#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">>[</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Column One'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Column Two'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Column Three'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Column Four'</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>To learn more about building linear layouts, see the community-contributed Medium article <a href="https://proandroiddev.com/flutter-for-android-developers-how-to-design-linearlayout-in-flutter-5d819c0ddf1a">Flutter for Android Developers: How to design LinearLayout in Flutter</a>.</p><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-a-relativelayout">What is the equivalent of a RelativeLayout?</h3><a class="heading-link" href="#what-is-the-equivalent-of-a-relativelayout" aria-label="Link to 'What is the equivalent of a RelativeLayout?' section">#</a></div><p>A RelativeLayout lays your widgets out relative to each other. In Flutter, there are a few ways to achieve the same result.</p><p>You can achieve the result of a RelativeLayout by using a combination of Column, Row, and Stack widgets. You can specify rules for the widgets constructors on how the children are laid out relative to the parent.</p><p>For a good example of building a RelativeLayout in Flutter, see Collin's answer on <a href="https://stackoverflow.com/questions/44396075/equivalent-of-relativelayout-in-flutter">StackOverflow</a>.</p><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-a-scrollview">What is the equivalent of a ScrollView?</h3><a class="heading-link" href="#what-is-the-equivalent-of-a-scrollview" aria-label="Link to 'What is the equivalent of a ScrollView?' section">#</a></div><p>In Android, use a ScrollView to lay out your widgets—if the user's device has a smaller screen than your content, it scrolls.</p><p>In Flutter, the easiest way to do this is using the ListView widget. This might seem like overkill coming from Android, but in Flutter a ListView widget is both a ScrollView and an Android ListView.</p> <?code-excerpt "lib/layout.dart (list-view)"?> <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"> ListView</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> children: </span><span style="color:#BD2314">const</span><span style="color:#222222"> &#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">>[</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row One'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row Two'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row Three'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#0468D7"> Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row Four'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ],</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-handle-landscape-transitions-in-flutter">How do I handle landscape transitions in Flutter?</h3><a class="heading-link" href="#how-do-i-handle-landscape-transitions-in-flutter" aria-label="Link to 'How do I handle landscape transitions in Flutter?' section">#</a></div><p>FlutterView handles the config change if AndroidManifest.xml contains:</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0C7064">android:configChanges="orientation|screenSize"</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="gesture-detection-and-touch-event-handling">Gesture detection and touch event handling</h2><a class="heading-link" href="#gesture-detection-and-touch-event-handling" aria-label="Link to 'Gesture detection and touch event handling' section">#</a></div><div class="header-wrapper"><h3 id="how-do-i-add-an-onclick-listener-to-a-widget-in-flutter">How do I add an onClick listener to a widget in Flutter?</h3><a class="heading-link" href="#how-do-i-add-an-onclick-listener-to-a-widget-in-flutter" aria-label="Link to 'How do I add an onClick listener to a widget in Flutter?' section">#</a></div><p>In Android, you can attach onClick to views such as button by calling the method 'setOnClickListener'.</p><p>In Flutter there are two ways of adding touch listeners:</p><ol><li>If the Widget supports event detection, pass a function to it and handle it in the function. For example, the ElevatedButton has an <code>onPressed</code> parameter:</li></ol> <?code-excerpt "lib/events.dart (on-pressed)"?> <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"> ElevatedButton</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onPressed: () {</span></span> <span class="line"><span style="color:#222222"> developer.</span><span style="color:#6200EE">log</span><span style="color:#222222">(</span><span style="color:#0C7064">'click'</span><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">'Button'</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><ol start="2"><li>If the Widget doesn't support event detection, wrap the widget in a GestureDetector and pass a function to the <code>onTap</code> parameter.</li></ol> <?code-excerpt "lib/events.dart (on-tap)"?> <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">class</span><span style="color:#0468D7"> SampleTapApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleTapApp</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"> 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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">GestureDetector</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onTap: () {</span></span> <span class="line"><span style="color:#222222"> developer.</span><span style="color:#6200EE">log</span><span style="color:#222222">(</span><span style="color:#0C7064">'tap'</span><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"> FlutterLogo</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> size: </span><span style="color:#0C7064">200</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-handle-other-gestures-on-widgets">How do I handle other gestures on widgets?</h3><a class="heading-link" href="#how-do-i-handle-other-gestures-on-widgets" aria-label="Link to 'How do I handle other gestures on widgets?' section">#</a></div><p>Using the GestureDetector, you can listen to a wide range of Gestures such as:</p><ul><li><p>Tap</p><ul><li><code>onTapDown</code> - A pointer that might cause a tap has contacted the screen at a particular location.</li><li><code>onTapUp</code> - A pointer that triggers a tap has stopped contacting the screen at a particular location.</li><li><code>onTap</code> - A tap has occurred.</li><li><code>onTapCancel</code> - The pointer that previously triggered the <code>onTapDown</code> won't cause a tap.</li></ul></li><li><p>Double tap</p><ul><li><code>onDoubleTap</code> - The user tapped the screen at the same location twice in quick succession.</li></ul></li><li><p>Long press</p><ul><li><code>onLongPress</code> - A pointer has remained in contact with the screen at the same location for a long period of time.</li></ul></li><li><p>Vertical drag</p><ul><li><code>onVerticalDragStart</code> - A pointer has contacted the screen and might begin to move vertically.</li><li><code>onVerticalDragUpdate</code> - A pointer in contact with the screen has moved further in the vertical direction.</li><li><code>onVerticalDragEnd</code> - A pointer that was previously in contact with the screen and moving vertically is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.</li></ul></li><li><p>Horizontal drag</p><ul><li><code>onHorizontalDragStart</code> - A pointer has contacted the screen and might begin to move horizontally.</li><li><code>onHorizontalDragUpdate</code> - A pointer in contact with the screen has moved further in the horizontal direction.</li><li><code>onHorizontalDragEnd</code> - A pointer that was previously in contact with the screen and moving horizontally is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.</li></ul></li></ul><p>The following example shows a <code>GestureDetector</code> that rotates the Flutter logo on a double tap:</p> <?code-excerpt "lib/events.dart (sample-app)"?> <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">class</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</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">&#x3C;</span><span style="color:#0468D7">SampleApp</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppState</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"> _SampleAppState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleApp</span><span style="color:#222222">></span></span> <span class="line"><span style="color:#BD2314"> with</span><span style="color:#0468D7"> SingleTickerProviderStateMixin</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> late</span><span style="color:#0468D7"> AnimationController</span><span style="color:#222222"> controller;</span></span> <span class="line"><span style="color:#BD2314"> late</span><span style="color:#0468D7"> CurvedAnimation</span><span style="color:#222222"> curve;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> controller = </span><span style="color:#0468D7">AnimationController</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> vsync: </span><span style="color:#BD2314">this</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> duration: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(milliseconds: </span><span style="color:#0C7064">2000</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> curve = </span><span style="color:#0468D7">CurvedAnimation</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> parent: controller,</span></span> <span class="line"><span style="color:#222222"> curve: </span><span style="color:#0468D7">Curves</span><span style="color:#222222">.easeIn,</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">GestureDetector</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onDoubleTap: () {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (controller.isCompleted) {</span></span> <span class="line"><span style="color:#222222"> controller.</span><span style="color:#6200EE">reverse</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#BD2314">else</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#222222"> controller.</span><span style="color:#6200EE">forward</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:#0468D7">RotationTransition</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> turns: curve,</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> FlutterLogo</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> size: </span><span style="color:#0C7064">200</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> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="listviews-adapters">Listviews &amp; adapters</h2><a class="heading-link" href="#listviews-adapters" aria-label="Link to 'Listviews &amp; adapters' section">#</a></div><div class="header-wrapper"><h3 id="what-is-the-alternative-to-a-listview-in-flutter">What is the alternative to a ListView in Flutter?</h3><a class="heading-link" href="#what-is-the-alternative-to-a-listview-in-flutter" aria-label="Link to 'What is the alternative to a ListView in Flutter?' section">#</a></div><p>The equivalent to a ListView in Flutter is … a ListView!</p><p>In an Android ListView, you create an adapter and pass it into the ListView, which renders each row with what your adapter returns. However, you have to make sure you recycle your rows, otherwise, you get all sorts of crazy visual glitches and memory issues.</p><p>Due to Flutter's immutable widget pattern, you pass a list of widgets to your ListView, and Flutter takes care of making sure that scrolling is fast and smooth.</p> <?code-excerpt "lib/listview.dart"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">ListView</span><span style="color:#222222">(children: </span><span style="color:#6200EE">_getListData</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> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">> </span><span style="color:#6200EE">_getListData</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">> widgets = [];</span></span> <span class="line"><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#0468D7">int</span><span style="color:#222222"> i = </span><span style="color:#0C7064">0</span><span style="color:#222222">; i &#x3C; </span><span style="color:#0C7064">100</span><span style="color:#222222">; i++) {</span></span> <span class="line"><span style="color:#222222"> widgets.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span><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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row </span><span style="color:#0C7064">$</span><span style="color:#222222">i</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:#BD2314"> return</span><span style="color:#222222"> widgets;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-know-which-list-item-is-clicked-on">How do I know which list item is clicked on?</h3><a class="heading-link" href="#how-do-i-know-which-list-item-is-clicked-on" aria-label="Link to 'How do I know which list item is clicked on?' section">#</a></div><p>In Android, the ListView has a method to find out which item was clicked, 'onItemClickListener'. In Flutter, use the touch handling provided by the passed-in widgets.</p> <?code-excerpt "lib/list_item_tapped.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:developer'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> developer;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">ListView</span><span style="color:#222222">(children: </span><span style="color:#6200EE">_getListData</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> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">> </span><span style="color:#6200EE">_getListData</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">> widgets = [];</span></span> <span class="line"><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#0468D7">int</span><span style="color:#222222"> i = </span><span style="color:#0C7064">0</span><span style="color:#222222">; i &#x3C; </span><span style="color:#0C7064">100</span><span style="color:#222222">; i++) {</span></span> <span class="line"><span style="color:#222222"> widgets.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#0468D7"> GestureDetector</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onTap: () {</span></span> <span class="line"><span style="color:#222222"> developer.</span><span style="color:#6200EE">log</span><span style="color:#222222">(</span><span style="color:#0C7064">'row tapped'</span><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">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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row </span><span style="color:#0C7064">$</span><span style="color:#222222">i</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:#BD2314"> return</span><span style="color:#222222"> widgets;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-update-listviews-dynamically">How do I update ListView's dynamically?</h3><a class="heading-link" href="#how-do-i-update-listviews-dynamically" aria-label="Link to 'How do I update ListView's dynamically?' section">#</a></div><p>On Android, you update the adapter and call <code>notifyDataSetChanged</code>.</p><p>In Flutter, if you were to update the list of widgets inside a <code>setState()</code>, you would quickly see that your data did not change visually. This is because when <code>setState()</code> is called, the Flutter rendering engine looks at the widget tree to see if anything has changed. When it gets to your <code>ListView</code>, it performs a <code>==</code> check, and determines that the two <code>ListView</code>s are the same. Nothing has changed, so no update is required.</p><p>For a simple way to update your <code>ListView</code>, create a new <code>List</code> inside of <code>setState()</code>, and copy the data from the old list to the new list. While this approach is simple, it is not recommended for large data sets, as shown in the next example.</p> <?code-excerpt "lib/listview_dynamic.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:developer'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> developer;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">> widgets = [];</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#0468D7">int</span><span style="color:#222222"> i = </span><span style="color:#0C7064">0</span><span style="color:#222222">; i &#x3C; </span><span style="color:#0C7064">100</span><span style="color:#222222">; i++) {</span></span> <span class="line"><span style="color:#222222"> widgets.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span><span style="color:#6200EE">getRow</span><span style="color:#222222">(i));</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">ListView</span><span style="color:#222222">(children: widgets),</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:#0468D7"> Widget</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> GestureDetector</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onTap: () {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> widgets = </span><span style="color:#0468D7">List</span><span style="color:#222222">.</span><span style="color:#6200EE">from</span><span style="color:#222222">(widgets);</span></span> <span class="line"><span style="color:#222222"> widgets.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span><span style="color:#6200EE">getRow</span><span style="color:#222222">(widgets.length));</span></span> <span class="line"><span style="color:#222222"> developer.</span><span style="color:#6200EE">log</span><span style="color:#222222">(</span><span style="color:#0C7064">'row </span><span style="color:#0C7064">$</span><span style="color:#222222">i</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"> child: </span><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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row </span><span style="color:#0C7064">$</span><span style="color:#222222">i</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></code></pre></div></div><p>The recommended, efficient, and effective way to build a list uses a <code>ListView.Builder</code>. This method is great when you have a dynamic <code>List</code> or a <code>List</code> with very large amounts of data. This is essentially the equivalent of RecyclerView on Android, which automatically recycles list elements for you:</p> <?code-excerpt "lib/listview_builder.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:developer'</span><span style="color:#BD2314"> as</span><span style="color:#222222"> developer;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Widget</span><span style="color:#222222">> widgets = [];</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> @override</span></span> <span class="line"><span style="color:#BD2314"> void</span><span style="color:#6200EE"> initState</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> super</span><span style="color:#222222">.</span><span style="color:#6200EE">initState</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#BD2314"> for</span><span style="color:#222222"> (</span><span style="color:#0468D7">int</span><span style="color:#222222"> i = </span><span style="color:#0C7064">0</span><span style="color:#222222">; i &#x3C; </span><span style="color:#0C7064">100</span><span style="color:#222222">; i++) {</span></span> <span class="line"><span style="color:#222222"> widgets.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span><span style="color:#6200EE">getRow</span><span style="color:#222222">(i));</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </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: widgets.length,</span></span> <span class="line"><span style="color:#222222"> itemBuilder: (context, position) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(position);</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> <span class="line"><span style="color:#0468D7"> Widget</span><span style="color:#6200EE"> getRow</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#0468D7"> GestureDetector</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onTap: () {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#222222"> widgets.</span><span style="color:#6200EE">add</span><span style="color:#222222">(</span><span style="color:#6200EE">getRow</span><span style="color:#222222">(widgets.length));</span></span> <span class="line"><span style="color:#222222"> developer.</span><span style="color:#6200EE">log</span><span style="color:#222222">(</span><span style="color:#0C7064">'row </span><span style="color:#0C7064">$</span><span style="color:#222222">i</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"> child: </span><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">all</span><span style="color:#222222">(</span><span style="color:#0C7064">10</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Row </span><span style="color:#0C7064">$</span><span style="color:#222222">i</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></code></pre></div></div><p>Instead of creating a &quot;ListView&quot;, create a <code>ListView.builder</code> that takes two key parameters: the initial length of the list, and an <code>ItemBuilder</code> function.</p><p>The <code>ItemBuilder</code> function is similar to the <code>getView</code> function in an Android adapter; it takes a position, and returns the row you want rendered at that position.</p><p>Finally, but most importantly, notice that the <code>onTap()</code> function doesn't recreate the list anymore, but instead <code>.add</code>s to it.</p><div class="header-wrapper"><h2 id="working-with-text">Working with text</h2><a class="heading-link" href="#working-with-text" aria-label="Link to 'Working with text' section">#</a></div><div class="header-wrapper"><h3 id="how-do-i-set-custom-fonts-on-my-text-widgets">How do I set custom fonts on my Text widgets?</h3><a class="heading-link" href="#how-do-i-set-custom-fonts-on-my-text-widgets" aria-label="Link to 'How do I set custom fonts on my Text widgets?' section">#</a></div><p>In Android SDK (as of Android O), you create a Font resource file and pass it into the FontFamily param for your TextView.</p><p>In Flutter, place the font file in a folder and reference it in the <code>pubspec.yaml</code> file, similar to how you import images.</p><div class="code-block-wrapper language-yaml"><div class="code-block-body"><span class="code-block-language" title="Language yaml">yaml</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">fonts</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#222222"> - </span><span style="color:#0468D7">family</span><span style="color:#222222">: </span><span style="color:#0C7064">MyCustomFont</span></span> <span class="line"><span style="color:#0468D7"> fonts</span><span style="color:#222222">:</span></span> <span class="line"><span style="color:#222222"> - </span><span style="color:#0468D7">asset</span><span style="color:#222222">: </span><span style="color:#0C7064">fonts/MyCustomFont.ttf</span></span> <span class="line"><span style="color:#222222"> - </span><span style="color:#0468D7">style</span><span style="color:#222222">: </span><span style="color:#0C7064">italic</span></span></code></pre></div></div><p>Then assign the font to your <code>Text</code> widget:</p> <?code-excerpt "lib/text.dart (custom-font)"?> <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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#0C7064"> 'This is a custom font text'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> style: </span><span style="color:#0468D7">TextStyle</span><span style="color:#222222">(fontFamily: </span><span style="color:#0C7064">'MyCustomFont'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-style-my-text-widgets">How do I style my Text widgets?</h3><a class="heading-link" href="#how-do-i-style-my-text-widgets" aria-label="Link to 'How do I style my Text widgets?' section">#</a></div><p>Along with fonts, you can customize other styling elements on a <code>Text</code> widget. The style parameter of a <code>Text</code> widget takes a <code>TextStyle</code> object, where you can customize many parameters, such as:</p><ul><li>color</li><li>decoration</li><li>decorationColor</li><li>decorationStyle</li><li>fontFamily</li><li>fontSize</li><li>fontStyle</li><li>fontWeight</li><li>hashCode</li><li>height</li><li>inherit</li><li>letterSpacing</li><li>textBaseline</li><li>wordSpacing</li></ul><div class="header-wrapper"><h2 id="form-input">Form input</h2><a class="heading-link" href="#form-input" aria-label="Link to 'Form input' section">#</a></div><p>For more information on using Forms, see <a href="/cookbook/forms/retrieve-input">Retrieve the value of a text field</a>, from the <a href="/cookbook">Flutter cookbook</a>.</p><div class="header-wrapper"><h3 id="what-is-the-equivalent-of-a-hint-on-an-input">What is the equivalent of a &quot;hint&quot; on an Input?</h3><a class="heading-link" href="#what-is-the-equivalent-of-a-hint-on-an-input" aria-label="Link to 'What is the equivalent of a &quot;hint&quot; on an Input?' section">#</a></div><p>In Flutter, you can easily show a &quot;hint&quot; or a placeholder text for your input by adding an InputDecoration object to the decoration constructor parameter for the Text Widget.</p> <?code-excerpt "lib/form.dart (input-hint)" replace="/return const //g;/;//g"?> <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">Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">TextField</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> decoration: </span><span style="color:#0468D7">InputDecoration</span><span style="color:#222222">(hintText: </span><span style="color:#0C7064">'This is a hint'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222">)</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-show-validation-errors">How do I show validation errors?</h3><a class="heading-link" href="#how-do-i-show-validation-errors" aria-label="Link to 'How do I show validation errors?' section">#</a></div><p>Just as you would with a &quot;hint&quot;, pass an InputDecoration object to the decoration constructor for the Text widget.</p><p>However, you don't want to start off by showing an error. Instead, when the user has entered invalid data, update the state, and pass a new <code>InputDecoration</code> object.</p> <?code-excerpt "lib/validation_errors.dart"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleApp</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"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</span><span style="color:#222222">({</span><span style="color:#BD2314">super</span><span style="color:#222222">.key});</span></span> <span class="line"><span style="color:#6E6E70"> // This widget is the root of your application.</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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</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> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleAppPage</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"> SampleAppPage</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">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> </span><span style="color:#6200EE">createState</span><span style="color:#222222">() => </span><span style="color:#0468D7">_SampleAppPageState</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"> _SampleAppPageState</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> State</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">SampleAppPage</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222">? _errorText;</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"> Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> appBar: </span><span style="color:#0468D7">AppBar</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">'Sample App'</span><span style="color:#222222">),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">TextField</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> onSubmitted: (text) {</span></span> <span class="line"><span style="color:#6200EE"> setState</span><span style="color:#222222">(() {</span></span> <span class="line"><span style="color:#BD2314"> if</span><span style="color:#222222"> (!</span><span style="color:#6200EE">isEmail</span><span style="color:#222222">(text)) {</span></span> <span class="line"><span style="color:#222222"> _errorText = </span><span style="color:#0C7064">'Error: This is not an email'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> } </span><span style="color:#BD2314">else</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#222222"> _errorText = </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:#222222"> },</span></span> <span class="line"><span style="color:#222222"> decoration: </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">'This is a hint'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> errorText: </span><span style="color:#6200EE">_getErrorText</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> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222">? </span><span style="color:#6200EE">_getErrorText</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#222222"> _errorText;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#6200EE"> isEmail</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> em) {</span></span> <span class="line"><span style="color:#0468D7"> String</span><span style="color:#222222"> emailRegexp =</span></span> <span class="line"><span style="color:#0C7064"> r'^(([^&#x3C;>()[\]\\.,;:\s@\"]+(\.[^&#x3C;>()[\]\\.,;:\s@\"]+)*)|'</span></span> <span class="line"><span style="color:#0C7064"> r'(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|'</span></span> <span class="line"><span style="color:#0C7064"> r'(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7"> RegExp</span><span style="color:#222222"> regExp = </span><span style="color:#0468D7">RegExp</span><span style="color:#222222">(emailRegexp);</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> return</span><span style="color:#222222"> regExp.</span><span style="color:#6200EE">hasMatch</span><span style="color:#222222">(em);</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="flutter-plugins">Flutter plugins</h2><a class="heading-link" href="#flutter-plugins" aria-label="Link to 'Flutter plugins' section">#</a></div><div class="header-wrapper"><h3 id="how-do-i-access-the-gps-sensor">How do I access the GPS sensor?</h3><a class="heading-link" href="#how-do-i-access-the-gps-sensor" aria-label="Link to 'How do I access the GPS sensor?' section">#</a></div><p>Use the <a href="https://pub.dev/packages/geolocator"><code>geolocator</code></a> community plugin.</p><div class="header-wrapper"><h3 id="how-do-i-access-the-camera">How do I access the camera?</h3><a class="heading-link" href="#how-do-i-access-the-camera" aria-label="Link to 'How do I access the camera?' section">#</a></div><p>The <a href="https://pub.dev/packages/image_picker"><code>image_picker</code></a> plugin is popular for accessing the camera.</p><div class="header-wrapper"><h3 id="how-do-i-log-in-with-facebook">How do I log in with Facebook?</h3><a class="heading-link" href="#how-do-i-log-in-with-facebook" aria-label="Link to 'How do I log in with Facebook?' section">#</a></div><p>To Log in with Facebook, use the <a href="https://pub.dev/packages/flutter_facebook_login"><code>flutter_facebook_login</code></a> community plugin.</p><div class="header-wrapper"><h3 id="how-do-i-use-firebase-features">How do I use Firebase features?</h3><a class="heading-link" href="#how-do-i-use-firebase-features" aria-label="Link to 'How do I use Firebase features?' section">#</a></div><p>Most Firebase functions are covered by <a href="https://pub.dev/flutter/packages?q=firebase">first party plugins</a>. These plugins are first-party integrations, maintained by the Flutter team:</p><ul><li><a href="https://pub.dev/packages/google_mobile_ads"><code>google_mobile_ads</code></a> for Google Mobile Ads for Flutter</li><li><a href="https://pub.dev/packages/firebase_analytics"><code>firebase_analytics</code></a> for Firebase Analytics</li><li><a href="https://pub.dev/packages/firebase_auth"><code>firebase_auth</code></a> for Firebase Auth</li><li><a href="https://pub.dev/packages/firebase_database"><code>firebase_database</code></a> for Firebase RTDB</li><li><a href="https://pub.dev/packages/firebase_storage"><code>firebase_storage</code></a> for Firebase Cloud Storage</li><li><a href="https://pub.dev/packages/firebase_messaging"><code>firebase_messaging</code></a> for Firebase Messaging (FCM)</li><li><a href="https://pub.dev/packages/flutter_firebase_ui"><code>flutter_firebase_ui</code></a> for quick Firebase Auth integrations (Facebook, Google, Twitter and email)</li><li><a href="https://pub.dev/packages/cloud_firestore"><code>cloud_firestore</code></a> for Firebase Cloud Firestore</li></ul><p>You can also find some third-party Firebase plugins on pub.dev that cover areas not directly covered by the first-party plugins.</p><div class="header-wrapper"><h3 id="how-do-i-build-my-own-custom-native-integrations">How do I build my own custom native integrations?</h3><a class="heading-link" href="#how-do-i-build-my-own-custom-native-integrations" aria-label="Link to 'How do I build my own custom native integrations?' section">#</a></div><p>If there is platform-specific functionality that Flutter or its community Plugins are missing, you can build your own following the <a href="/packages-and-plugins/developing-packages">developing packages and plugins</a> page.</p><p>Flutter's plugin architecture, in a nutshell, is much like using an Event bus in Android: you fire off a message and let the receiver process and emit a result back to you. In this case, the receiver is code running on the native side on Android or iOS.</p><div class="header-wrapper"><h3 id="how-do-i-use-the-ndk-in-my-flutter-application">How do I use the NDK in my Flutter application?</h3><a class="heading-link" href="#how-do-i-use-the-ndk-in-my-flutter-application" aria-label="Link to 'How do I use the NDK in my Flutter application?' section">#</a></div><p>If you use the NDK in your current Android application and want your Flutter application to take advantage of your native libraries then it's possible by building a custom plugin.</p><p>Your custom plugin first talks to your Android app, where you call your <code>native</code> functions over JNI. Once a response is ready, send a message back to Flutter and render the result.</p><p>Calling native code directly from Flutter is currently not supported.</p><div class="header-wrapper"><h2 id="themes">Themes</h2><a class="heading-link" href="#themes" aria-label="Link to 'Themes' section">#</a></div><div class="header-wrapper"><h3 id="how-do-i-theme-my-app">How do I theme my app?</h3><a class="heading-link" href="#how-do-i-theme-my-app" aria-label="Link to 'How do I theme my app?' section">#</a></div><p>Out of the box, Flutter comes with a beautiful implementation of Material Design, which takes care of a lot of styling and theming needs that you would typically do. Unlike Android where you declare themes in XML and then assign it to your application using AndroidManifest.xml, in Flutter you declare themes in the top level widget.</p><p>To take full advantage of Material Components in your app, you can declare a top level widget <code>MaterialApp</code> as the entry point to your application. MaterialApp is a convenience widget that wraps a number of widgets that are commonly required for applications implementing Material Design. It builds upon a WidgetsApp by adding Material specific functionality.</p><p>You can also use a <code>WidgetsApp</code> as your app widget, which provides some of the same functionality, but is not as rich as <code>MaterialApp</code>.</p><p>To customize the colors and styles of any child components, pass a <code>ThemeData</code> object to the <code>MaterialApp</code> widget. For example, in the code below, the color scheme from seed is set to deepPurple and text selection color is red.</p> <?code-excerpt "lib/theme.dart (theme)"?> <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">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">class</span><span style="color:#0468D7"> SampleApp</span><span style="color:#BD2314"> extends</span><span style="color:#0468D7"> StatelessWidget</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> SampleApp</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"> 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"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> title: </span><span style="color:#0C7064">'Sample App'</span><span style="color:#222222">,</span></span> <span class="line"><span style="color:#222222"> theme: </span><span style="color:#0468D7">ThemeData</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> colorScheme: </span><span style="color:#0468D7">ColorScheme</span><span style="color:#222222">.</span><span style="color:#6200EE">fromSeed</span><span style="color:#222222">(seedColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.deepPurple),</span></span> <span class="line"><span style="color:#222222"> textSelectionTheme:</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> TextSelectionThemeData</span><span style="color:#222222">(selectionColor: </span><span style="color:#0468D7">Colors</span><span style="color:#222222">.red),</span></span> <span class="line"><span style="color:#222222"> ),</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#BD2314">const</span><span style="color:#0468D7"> SampleAppPage</span><span style="color:#222222">(),</span></span> <span class="line"><span style="color:#222222"> );</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h2 id="databases-and-local-storage">Databases and local storage</h2><a class="heading-link" href="#databases-and-local-storage" aria-label="Link to 'Databases and local storage' section">#</a></div><div class="header-wrapper"><h3 id="how-do-i-access-shared-preferences">How do I access Shared Preferences?</h3><a class="heading-link" href="#how-do-i-access-shared-preferences" aria-label="Link to 'How do I access Shared Preferences?' section">#</a></div><p>In Android, you can store a small collection of key-value pairs using the SharedPreferences API.</p><p>In Flutter, access this functionality using the <a href="https://pub.dev/packages/shared_preferences">Shared_Preferences plugin</a>. This plugin wraps the functionality of both Shared Preferences and NSUserDefaults (the iOS equivalent).</p> <?code-excerpt "lib/shared_prefs.dart"?> <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">import</span><span style="color:#0C7064"> 'dart:async'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:flutter/material.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">import</span><span style="color:#0C7064"> 'package:shared_preferences/shared_preferences.dart'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6200EE"> runApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#BD2314"> const</span><span style="color:#0468D7"> MaterialApp</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> home: </span><span style="color:#0468D7">Scaffold</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> body: </span><span style="color:#0468D7">Center</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: _incrementCounter,</span></span> <span class="line"><span style="color:#222222"> child: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(</span><span style="color:#0C7064">'Increment Counter'</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> <span class="line"></span> <span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#BD2314">void</span><span style="color:#222222">> </span><span style="color:#6200EE">_incrementCounter</span><span style="color:#222222">() </span><span style="color:#BD2314">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#0468D7"> SharedPreferences</span><span style="color:#222222"> prefs = </span><span style="color:#BD2314">await</span><span style="color:#0468D7"> SharedPreferences</span><span style="color:#222222">.</span><span style="color:#6200EE">getInstance</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#0468D7"> int</span><span style="color:#222222"> counter = (prefs.</span><span style="color:#6200EE">getInt</span><span style="color:#222222">(</span><span style="color:#0C7064">'counter'</span><span style="color:#222222">) ?? </span><span style="color:#0C7064">0</span><span style="color:#222222">) + </span><span style="color:#0C7064">1</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#BD2314"> await</span><span style="color:#222222"> prefs.</span><span style="color:#6200EE">setInt</span><span style="color:#222222">(</span><span style="color:#0C7064">'counter'</span><span style="color:#222222">, counter);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="how-do-i-access-sqlite-in-flutter">How do I access SQLite in Flutter?</h3><a class="heading-link" href="#how-do-i-access-sqlite-in-flutter" aria-label="Link to 'How do I access SQLite in Flutter?' section">#</a></div><p>In Android, you use SQLite to store structured data that you can query using SQL.</p><p>In Flutter, for macOS, Android, or iOS, access this functionality using the <a href="https://pub.dev/packages/sqflite">SQFlite</a> plugin.</p><div class="header-wrapper"><h2 id="debugging">Debugging</h2><a class="heading-link" href="#debugging" aria-label="Link to 'Debugging' section">#</a></div><div class="header-wrapper"><h3 id="what-tools-can-i-use-to-debug-my-app-in-flutter">What tools can I use to debug my app in Flutter?</h3><a class="heading-link" href="#what-tools-can-i-use-to-debug-my-app-in-flutter" aria-label="Link to 'What tools can I use to debug my app in Flutter?' section">#</a></div><p>Use the <a href="/tools/devtools">DevTools</a> suite for debugging Flutter or Dart apps.</p><p>DevTools includes support for profiling, examining the heap, inspecting the widget tree, logging diagnostics, debugging, observing executed lines of code, debugging memory leaks and memory fragmentation. For more information, check out the <a href="/tools/devtools">DevTools</a> documentation.</p><div class="header-wrapper"><h2 id="notifications">Notifications</h2><a class="heading-link" href="#notifications" aria-label="Link to 'Notifications' section">#</a></div><div class="header-wrapper"><h3 id="how-do-i-set-up-push-notifications">How do I set up push notifications?</h3><a class="heading-link" href="#how-do-i-set-up-push-notifications" aria-label="Link to 'How do I set up push notifications?' section">#</a></div><p>In Android, you use Firebase Cloud Messaging to set up push notifications for your app.</p><p>In Flutter, access this functionality using the <a href="https://github.com/firebase/flutterfire/tree/master/packages/firebase_messaging">Firebase Messaging</a> plugin. For more information on using the Firebase Cloud Messaging API, see the <a href="https://pub.dev/packages/firebase_messaging"><code>firebase_messaging</code></a> plugin documentation.</p><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-10-17.</span> <a href="https://github.com/flutter/website/tree/main/src/content/get-started/flutter-for/android-devs.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/flutter-for/android-devs/&page-source=https://github.com/flutter/website/tree/main/src/content/get-started/flutter-for/android-devs.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>

Pages: 1 2 3 4 5 6 7 8 9 10