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?v=4"></head><body><section id="cookie-notice"><div class="container"><p>docs.flutter.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic. <a href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a>.</p><button id="cookie-consent" class="filled-button">OK, got it</button></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-ND4LWWZ" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="site-banner" role="alert"><p>Flutter 3.29 is here with a bouquet of performance and fidelity improvements for your apps! <a href="https://medium.com/flutter/whats-new-in-flutter-3-29-f90c380c2317">Learn more</a><br></p></div><header class="site-header"><a href="#document-title" id="skip-to-main" class="filled-button" tabindex="1">Skip to main content</a><nav class="navbar"><div id="site-switcher" class="dropdown"><button class="dropdown-button site-wordmark" aria-expanded="false" aria-controls="site-switcher-menu" aria-label="Switch between Flutter and Dart sites"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span> <span class="subtype">Docs</span> <span class="material-symbols" aria-hidden="true">unfold_more</span></button><div class="dropdown-content" id="site-switcher-menu"><nav class="dropdown-menu" role="menu"><ul><li role="presentation"><a href="https://flutter.dev" class="site-wordmark" role="menuitem" title="Flutter homepage" aria-label="Go to the Flutter homepage"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span></a></li><li role="presentation"><a href="https://docs.flutter.dev" class="site-wordmark current-site" role="menuitem" aria-current="true" title="Flutter docs homepage" aria-label="Go to the Flutter docs homepage"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span> <span class="subtype">Docs</span></a></li><li role="presentation"><a href="https://api.flutter.dev" class="site-wordmark" role="menuitem" title="Flutter API reference" aria-label="Go to the Flutter API reference"><img src="/assets/images/branding/flutter/logo/default.svg" alt="Flutter logo" width="28"> <span>Flutter</span> <span class="subtype">API</span></a></li><li aria-hidden="true" class="dropdown-divider" role="separator"></li><li role="presentation"><a href="https://dart.dev" class="site-wordmark" role="menuitem" title="Dart homepage" aria-label="Go to the Dart homepage"><img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28"> <span>Dart</span></a></li><li role="presentation"><a href="https://dartpad.dev" class="site-wordmark" role="menuitem" title="DartPad playground" aria-label="Go to the DartPad playground"><img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28"> <span>DartPad</span></a></li><li role="presentation"><a href="https://pub.dev" class="site-wordmark" role="menuitem" title="pub.dev homepage" aria-label="Go to the pub.dev homepage"><img src="/assets/images/branding/dart/logo.svg" alt="Dart logo" width="28" height="28"> <span>pub.dev</span></a></li></ul></nav></div></div><div class="navbar-contents"><ul class="navbar-nav"><li class="nav-item"><a class="nav-link" href="https://flutter.dev">Homepage</a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev/community">Community</a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev">Packages</a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev">API reference</a></li></ul><form action="/search/" class="site-header__search"><input class="site-header__searchfield search-field" type="search" name="q" id="q" autocomplete="off" placeholder="Search" aria-label="Search"></form><a href="/search" id="fallback-search-button" class="icon-button" aria-label="Navigate to the docs search page." title="Navigate to the docs search page."><span class="material-symbols" aria-hidden="true">search</span> </a><a id="call-to-action" class="filled-button" href="/get-started/install/">Get started</a> <button id="menu-toggle" class="icon-button" type="button" aria-controls="sidenav" aria-label="Toggle navigation" title="Toggle navigation"><span class="material-symbols" aria-hidden="true">menu</span></button></div></nav></header><div id="site-below-header"><div id="site-main-row"><div id="sidenav" class="site-sidebar"><nav><ul><li class="nav-header">Get started</li><li class="nav-item"><a class="nav-link" href="/get-started/install"><div><span>Set up Flutter</span></div></a></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#sidenav-3" role="button" aria-expanded="true" aria-controls="sidenav-3"><span>Learn Flutter</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="sidenav-3"><li class="nav-item"><a class="nav-link" href="/get-started/learn-flutter"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/codelab"><div><span>Write your first app</span></div></a></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#sidenav-3-3" role="button" aria-expanded="true" aria-controls="sidenav-3-3"><span>Learn the fundamentals</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="sidenav-3-3"><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/dart"><div><span>Intro to Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/widgets"><div><span>Widgets</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/layout"><div><span>Layout</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/state-management"><div><span>State management</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/user-input"><div><span>Handling user input</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/networking"><div><span>Networking and data</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/fundamentals/local-caching"><div><span>Local data and caching</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#sidenav-3-4" role="button" aria-expanded="true" aria-controls="sidenav-3-4"><span>From another platform?</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="sidenav-3-4"><li class="nav-item"><a class="nav-link active" href="/get-started/flutter-for/android-devs"><div><span>Flutter for Android devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/compose-devs"><div><span>Flutter for Jetpack Compose devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/swiftui-devs"><div><span>Flutter for SwiftUI devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/uikit-devs"><div><span>Flutter for UIKit devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/react-native-devs"><div><span>Flutter for React Native devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/web-devs"><div><span>Flutter for web devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/xamarin-forms-devs"><div><span>Flutter for Xamarin.Forms devs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/declarative"><div><span>Introduction to declarative UI</span></div></a></li><li class="nav-item"><a class="nav-link" href="/get-started/flutter-for/dart-swift-concurrency"><div><span>Flutter versus Swift concurrency</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/codelabs"><div><span>Codelabs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook"><div><span>Cookbook</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/samples" target="_blank" rel="noopener"><div><span>Demos and samples</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-4" role="button" aria-expanded="false" aria-controls="sidenav-4"><span>Stay up to date</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-4"><li class="nav-item"><a class="nav-link" href="/release/upgrade"><div><span>Upgrade</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/archive"><div><span>SDK archive</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/release/whats-new"><div><span>What's new</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/release-notes"><div><span>Release notes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes"><div><span>Breaking changes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/compatibility-policy"><div><span>Compatibility policy</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-5" role="button" aria-expanded="false" aria-controls="sidenav-5"><span>App solutions</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-1" role="button" aria-expanded="false" aria-controls="sidenav-5-1"><span>AI</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-1"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-1-1" role="button" aria-expanded="false" aria-controls="sidenav-5-1-1"><span>AI Toolkit guide</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-1-1"><li class="nav-item"><a class="nav-link" href="/ai-toolkit"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/user-experience"><div><span>User experience</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/feature-integration"><div><span>Feature integration</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/custom-llm-providers"><div><span>Custom LLM providers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ai-toolkit/chat-client-sample"><div><span>Chat client sample</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=1AuzJEiHjO4" target="_blank" rel="noopener"><div><span>Build with Google AI Dart SDK (video)</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-2" role="button" aria-expanded="false" aria-controls="sidenav-5-2"><span>Firebase & Firestore</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter" target="_blank" rel="noopener"><div><span>Discover Firebase for Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://www.youtube.com/watch?v=wUSkeTaBonA" target="_blank" rel="noopener"><div><span>Get to know Firebase for Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener"><div><span>Add a user authentication flow to a Flutter app using FirebaseUI</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-get-to-know-web" target="_blank" rel="noopener"><div><span>Get to know Firebase for web</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-3" role="button" aria-expanded="false" aria-controls="sidenav-5-3"><span>Games</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-3"><li class="nav-item"><a class="nav-link" href="/resources/games-toolkit"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/achievements-leaderboard"><div><span>Add achievements and leaderboards</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/build-leaderboards-with-firestore#0" target="_blank" rel="noopener"><div><span>Build leaderboards with Firestore</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads"><div><span>Add advertising</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/games/firestore-multiplayer"><div><span>Add multiplayer support</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener"><div><span>Add in-app purchases</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/codelabs/firebase-auth-in-flutter-apps" target="_blank" rel="noopener"><div><span>Add user authentication</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/crashlytics/get-started?platform=flutter" target="_blank" rel="noopener"><div><span>Debug using Crashlytics</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-flame-brick-breaker" target="_blank" rel="noopener"><div><span>Intro to Flame with Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4" role="button" aria-expanded="false" aria-controls="sidenav-5-4"><span>Monetization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4-1" role="button" aria-expanded="false" aria-controls="sidenav-5-4-1"><span>Advertising</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4-1"><li class="nav-item"><a class="nav-link" href="/resources/ads-overview"><div><span>Ads overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/google-mobile-ads"><div><span>Add advertising</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-ads-in-flutter" target="_blank" rel="noopener"><div><span>Add AdMob ads to your Flutter app</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/admob-inline-ads-in-flutter" target="_blank" rel="noopener"><div><span>Add an AdMob banner and native inline ads</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/admob/flutter/mediation" target="_blank" rel="noopener"><div><span>Google AdMob mediation</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/interactive_media_ads" target="_blank" rel="noopener"><div><span>Interactive Media Ads SDK</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4-2" role="button" aria-expanded="false" aria-controls="sidenav-5-4-2"><span>In-app purchases</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4-2"><li class="nav-item"><a class="nav-link" href="/resources/in-app-purchases-overview"><div><span>In-app purchases overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/flutter-in-app-purchases" target="_blank" rel="noopener"><div><span>Add in-app purchases</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-4-3" role="button" aria-expanded="false" aria-controls="sidenav-5-4-3"><span>Payments</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-4-3"><li class="nav-item"><a class="nav-link" href="/resources/payments-overview"><div><span>Payments overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/pay" target="_blank" rel="noopener"><div><span>Google pay package</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-5" role="button" aria-expanded="false" aria-controls="sidenav-5-5"><span>Maps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-5"><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/google-maps-in-flutter" target="_blank" rel="noopener"><div><span>Add Google maps to a Flutter app</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://developers.google.com/maps/flutter-package" target="_blank" rel="noopener"><div><span>Google Maps package</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-5-6" role="button" aria-expanded="false" aria-controls="sidenav-5-6"><span>News</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/resources/news-toolkit"><div><span>Build a news app</span></div></a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-header">User interface</li><li class="nav-item"><a class="nav-link" href="/ui"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/widgets"><div><span>Widget catalog</span></div></a></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-10" role="button" aria-expanded="false" aria-controls="sidenav-10"><span>Layout</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-10"><li class="nav-item"><a class="nav-link" href="/ui/layout"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/tutorial"><div><span>Build a layout</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-10-3" role="button" aria-expanded="false" aria-controls="sidenav-10-3"><span>Lists & grids</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-10-3"><li class="nav-item"><a class="nav-link" href="/cookbook/lists/basic-list"><div><span>Create and use lists</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/horizontal-list"><div><span>Create a horizontal list</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/grid-lists"><div><span>Create a grid view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/mixed-list"><div><span>Create lists with different types of items</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/spaced-items"><div><span>Create lists with spaced items</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/long-lists"><div><span>Work with long lists</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-10-4" role="button" aria-expanded="false" aria-controls="sidenav-10-4"><span>Scrolling</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-10-4"><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/scrolling/slivers"><div><span>Use slivers to achieve fancy scrolling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/lists/floating-app-bar"><div><span>Place a floating app bar above a list</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/parallax-scrolling"><div><span>Create a scrolling parallax effect</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-11" role="button" aria-expanded="false" aria-controls="sidenav-11"><span>Adaptive & responsive design</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-11"><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/general"><div><span>General approach</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/safearea-mediaquery"><div><span>SafeArea & MediaQuery</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/large-screens"><div><span>Large screens & foldables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/input"><div><span>User input & accessibility</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/capabilities"><div><span>Capabilities & policies</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/platform-adaptations"><div><span>Automatic platform adaptations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/best-practices"><div><span>Best practices</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/adaptive-responsive/more-info"><div><span>Additional resources</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-12" role="button" aria-expanded="false" aria-controls="sidenav-12"><span>Design & theming</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-12"><li class="nav-item"><a class="nav-link" href="/cookbook/design/themes"><div><span>Share styles with themes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/design/material"><div><span>Material design</span></div></a></li><li class="nav-item"><a class="nav-link" href="/release/breaking-changes/material-3-migration"><div><span>Migrate to Material 3</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-12-4" role="button" aria-expanded="false" aria-controls="sidenav-12-4"><span>Text</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-12-4"><li class="nav-item"><a class="nav-link" href="/ui/design/text/typography"><div><span>Fonts & typography</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/fonts"><div><span>Use a custom font</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/package-fonts"><div><span>Export fonts from a package</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/packages/google_fonts" target="_blank" rel="noopener"><div><span>Google Fonts package</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-12-5" role="button" aria-expanded="false" aria-controls="sidenav-12-5"><span>Custom graphics</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-12-5"><li class="nav-item"><a class="nav-link" href="/ui/design/graphics/fragment-shaders"><div><span>Use custom fragment shaders</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-13" role="button" aria-expanded="false" aria-controls="sidenav-13"><span>Interactivity</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-13"><li class="nav-item"><a class="nav-link" href="/ui/interactivity"><div><span>Add interactivity to your app</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-13-2" role="button" aria-expanded="false" aria-controls="sidenav-13-2"><span>Gestures</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-13-2"><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/handling-taps"><div><span>Handle taps</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/gestures/drag-outside"><div><span>Drag an object outside an app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/drag-a-widget"><div><span>Drag a UI element within an app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/ripples"><div><span>Add Material touch ripples</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/gestures/dismissible"><div><span>Implement swipe to dismiss</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-13-3" role="button" aria-expanded="false" aria-controls="sidenav-13-3"><span>Input & forms</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-13-3"><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-input"><div><span>Create and style a text field</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/retrieve-input"><div><span>Retrieve the value of a text field</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/text-field-changes"><div><span>Handle changes to a text field</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/focus"><div><span>Manage focus in text fields</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/forms/validation"><div><span>Build a form with validation</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/snackbars"><div><span>Display a snackbar</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/actions-and-shortcuts"><div><span>Implement actions & shortcuts</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/interactivity/focus"><div><span>Manage keyboard focus</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-14" role="button" aria-expanded="false" aria-controls="sidenav-14"><span>Assets & media</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-14"><li class="nav-item"><a class="nav-link" href="/ui/assets/assets-and-images"><div><span>Add assets and images</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/network-image"><div><span>Display images from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/images/fading-in-images"><div><span>Fade in images with a placeholder</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/plugins/play-video"><div><span>Play and pause a video</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/assets/asset-transformation"><div><span>Transform assets at build time</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-15" role="button" aria-expanded="false" aria-controls="sidenav-15"><span>Navigation & routing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-15"><li class="nav-item"><a class="nav-link" href="/ui/navigation"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/tabs"><div><span>Add tabs to your app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/navigation-basics"><div><span>Navigate to a new screen and back</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/passing-data"><div><span>Send data to a new screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/returning-data"><div><span>Return data from a screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/design/drawer"><div><span>Add a drawer to a screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/deep-linking"><div><span>Set up deep linking</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-app-links"><div><span>Set up app links for Android</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/navigation/set-up-universal-links"><div><span>Set up universal links for iOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/navigation/url-strategies"><div><span>Configure web URL strategies</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-16" role="button" aria-expanded="false" aria-controls="sidenav-16"><span>Animations & transitions</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-16"><li class="nav-item"><a class="nav-link" href="/ui/animations"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/tutorial"><div><span>Tutorial</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/implicit-animations"><div><span>Implicit animations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/animated-container"><div><span>Animate the properties of a container</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/opacity-animation"><div><span>Fade a widget in and out</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/hero-animations"><div><span>Hero animations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/page-route-animation"><div><span>Animate a page route transition</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/animation/physics-simulation"><div><span>Animate using a physics simulation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/staggered-animations"><div><span>Staggered animations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/effects/staggered-menu-animation"><div><span>Create a staggered menu animation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/animations/overview"><div><span>API overview</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-17" role="button" aria-expanded="false" aria-controls="sidenav-17"><span>Accessibility & internationalization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-17"><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/accessibility"><div><span>Accessibility</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/accessibility-and-internationalization/internationalization"><div><span>Internationalization</span></div></a></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-header">Beyond UI</li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-20" role="button" aria-expanded="false" aria-controls="sidenav-20"><span>Data & backend</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20"><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-1" role="button" aria-expanded="false" aria-controls="sidenav-20-1"><span>State management</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-1"><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/intro"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/declarative"><div><span>Think declaratively</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/ephemeral-vs-app"><div><span>Ephemeral vs app state</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/simple"><div><span>Simple app state management</span></div></a></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/state-mgmt/options"><div><span>Options</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-2" role="button" aria-expanded="false" aria-controls="sidenav-20-2"><span>Networking & http</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-2"><li class="nav-item"><a class="nav-link" href="/data-and-backend/networking"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/fetch-data"><div><span>Fetch data from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/authenticated-requests"><div><span>Make authenticated requests</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/send-data"><div><span>Send data to the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/update-data"><div><span>Update data over the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/delete-data"><div><span>Delete data on the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/web-sockets"><div><span>Communicate with WebSockets</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-3" role="button" aria-expanded="false" aria-controls="sidenav-20-3"><span>Serialization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-3"><li class="nav-item"><a class="nav-link" href="/data-and-backend/serialization/json"><div><span>JSON serialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/networking/background-parsing"><div><span>Parse JSON in the background</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-4" role="button" aria-expanded="false" aria-controls="sidenav-20-4"><span>Persistence</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-4"><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/key-value"><div><span>Store key-value data on disk</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/reading-writing-files"><div><span>Read and write files</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/persistence/sqlite"><div><span>Persist data with SQLite</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-20-5" role="button" aria-expanded="false" aria-controls="sidenav-20-5"><span>Firebase</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-20-5"><li class="nav-item"><a class="nav-link" href="/data-and-backend/firebase"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://firebase.google.com/docs/flutter/setup" target="_blank" rel="noopener"><div><span>Add Firebase to your Flutter app</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/data-and-backend/google-apis"><div><span>Google APIs</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-21" role="button" aria-expanded="false" aria-controls="sidenav-21"><span>App architecture</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-21"><li class="nav-item"><a class="nav-link" href="/app-architecture"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/concepts"><div><span>Architecture concepts</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/guide"><div><span>Guide to app architecture</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-21-4" role="button" aria-expanded="false" aria-controls="sidenav-21-4"><span>Architecture case study</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-21-4"><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/ui-layer"><div><span>UI layer</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/data-layer"><div><span>Data layer</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/dependency-injection"><div><span>Dependency injection</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/case-study/testing"><div><span>Testing each layer</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/app-architecture/recommendations"><div><span>Recommendations</span></div></a></li><li class="nav-item"><a class="nav-link" href="/app-architecture/design-patterns"><div><span>Design patterns</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-22" role="button" aria-expanded="false" aria-controls="sidenav-22"><span>Platform integration</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22"><li class="nav-item"><a class="nav-link" href="/reference/supported-platforms"><div><span>Supported platforms</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/desktop"><div><span>Build desktop apps with Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/platform-channels"><div><span>Write platform-specific code</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-4" role="button" aria-expanded="false" aria-controls="sidenav-22-4"><span>Android</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-4"><li class="nav-item"><a class="nav-link" href="/platform-integration/android/install-android"><div><span>Add Android as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/splash-screen"><div><span>Add a splash screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/predictive-back"><div><span>Add predictive back</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/c-interop"><div><span>Bind to native code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/platform-views"><div><span>Host a native Android view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/call-jetpack-apis"><div><span>Calling JetPack APIs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/compose-activity"><div><span>Launch a Jetpack Compose activity</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/restore-state-android"><div><span>Restore state on Android</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/android/chromeos"><div><span>Target ChromeOS with Android</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-5" role="button" aria-expanded="false" aria-controls="sidenav-22-5"><span>iOS</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-5"><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/install-ios"><div><span>Add iOS as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-latest"><div><span>Flutter on latest iOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/apple-frameworks"><div><span>Leverage Apple's system libraries</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/launch-screen"><div><span>Add a launch screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-app-clip"><div><span>Add iOS App Clip support</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/app-extensions"><div><span>Add iOS app extensions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/c-interop"><div><span>Bind to native code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/platform-views"><div><span>Host a native iOS view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/ios-debugging"><div><span>Enable debugging on iOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/ios/restore-state-ios"><div><span>Restore state on iOS</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-6" role="button" aria-expanded="false" aria-controls="sidenav-22-6"><span>Linux</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-6"><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/install-linux"><div><span>Add Linux as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/linux/building"><div><span>Build a Linux app</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-7" role="button" aria-expanded="false" aria-controls="sidenav-22-7"><span>macOS</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-7"><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/install-macos"><div><span>Add macOS as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/building"><div><span>Build a macOS app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/c-interop"><div><span>Bind to native code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/macos/platform-views"><div><span>Host a native macOS view</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-8" role="button" aria-expanded="false" aria-controls="sidenav-22-8"><span>Web</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-8"><li class="nav-item"><a class="nav-link" href="/platform-integration/web"><div><span>Web support in Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/install-web"><div><span>Add web as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/building"><div><span>Build a web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/wasm"><div><span>Compile to WebAssembly</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/initialization"><div><span>Customize app initialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web"><div><span>Add Flutter to any web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-content-in-flutter"><div><span>Web content in Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/renderers"><div><span>Web renderers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/web-images"><div><span>Display images on the web</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/faq"><div><span>Web FAQ</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-22-9" role="button" aria-expanded="false" aria-controls="sidenav-22-9"><span>Windows</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-22-9"><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/install-windows"><div><span>Add Windows as build target</span></div></a></li><li class="nav-item"><a class="nav-link" href="/platform-integration/windows/building"><div><span>Build a Windows app</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-23" role="button" aria-expanded="false" aria-controls="sidenav-23"><span>Packages & plugins</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-23"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/using-packages"><div><span>Use packages & plugins</span></div></a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/developing-packages"><div><span>Develop packages & plugins</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-23-3" role="button" aria-expanded="false" aria-controls="sidenav-23-3"><span>Swift Package Manager</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-23-3"><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-app-developers"><div><span>For app developers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/swift-package-manager/for-plugin-authors"><div><span>For plugin authors</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/packages-and-plugins/favorites"><div><span>Flutter Favorites</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev/flutter" target="_blank" rel="noopener"><div><span>Package repository</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-24" role="button" aria-expanded="false" aria-controls="sidenav-24"><span>Testing & debugging</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24"><li class="nav-header">Testing</li><li class="nav-item"><a class="nav-link" href="/testing/overview"><div><span>Overview</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-24-3" role="button" aria-expanded="false" aria-controls="sidenav-24-3"><span>Unit testing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24-3"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/introduction"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/unit/mocking"><div><span>Mock dependencies</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-24-4" role="button" aria-expanded="false" aria-controls="sidenav-24-4"><span>Widget testing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24-4"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/introduction"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/finders"><div><span>Find widgets</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/scrolling"><div><span>Simulate scrolling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/widget/tap-drag"><div><span>Simulate user interaction</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-24-5" role="button" aria-expanded="false" aria-controls="sidenav-24-5"><span>Integration testing</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-24-5"><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/introduction"><div><span>Introduction</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/integration-tests"><div><span>Write and run an integration test</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/testing/integration/profiling"><div><span>Profile an integration test</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/testing/testing-plugins"><div><span>Test a plugin</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/plugins-in-tests"><div><span>Handle plugin code in tests</span></div></a></li><li class="nav-header">Debugging</li><li class="nav-item"><a class="nav-link" href="/testing/debugging"><div><span>Debugging tools</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/code-debugging"><div><span>Debug your app programmatically</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/native-debugging"><div><span>Use a native language debugger</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/common-errors"><div><span>Common Flutter errors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/errors"><div><span>Handle errors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/cookbook/maintenance/error-reporting"><div><span>Report errors to a service</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-25" role="button" aria-expanded="false" aria-controls="sidenav-25"><span>Performance & optimization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-25"><li class="nav-item"><a class="nav-link" href="/perf"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/impeller"><div><span>Impeller</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/best-practices"><div><span>Performance best practices</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/app-size"><div><span>App size</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/deferred-components"><div><span>Deferred components</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/rendering-performance"><div><span>Rendering performance</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/ui-performance"><div><span>Performance profiling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/web-performance"><div><span>Performance profiling for web</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/metrics"><div><span>Performance metrics</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/isolates"><div><span>Concurrency and isolates</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/faq"><div><span>Performance FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/perf/appendix"><div><span>Appendix</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-26" role="button" aria-expanded="false" aria-controls="sidenav-26"><span>Deployment</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-26"><li class="nav-item"><a class="nav-link" href="/deployment/obfuscate"><div><span>Obfuscate Dart code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors"><div><span>Create app flavors for Android</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/flavors-ios"><div><span>Create app flavors for iOS and macOS</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/android"><div><span>Build and release an Android app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/ios"><div><span>Build and release an iOS app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/macos"><div><span>Build and release a macOS app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/linux"><div><span>Build and release a Linux app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/windows"><div><span>Build and release a Windows app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/web"><div><span>Build and release a web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deployment/cd"><div><span>Set up continuous deployment</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-27" role="button" aria-expanded="false" aria-controls="sidenav-27"><span>Add to an existing app</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-27"><li class="nav-item"><a class="nav-link" href="/add-to-app"><div><span>Introduction</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-27-2" role="button" aria-expanded="false" aria-controls="sidenav-27-2"><span>Add to an Android app</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-27-2"><li class="nav-item"><a class="nav-link" href="/add-to-app/android/project-setup"><div><span>Set up Android project</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-screen"><div><span>Add a single Flutter screen</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-fragment"><div><span>Add a Flutter Fragment</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/add-flutter-view"><div><span>Add a Flutter View</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/android/plugin-setup"><div><span>Use a Flutter plugin</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-27-3" role="button" aria-expanded="false" aria-controls="sidenav-27-3"><span>Add to an iOS app</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-27-3"><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/project-setup"><div><span>Set up iOS project</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/ios/add-flutter-screen"><div><span>Add a single Flutter screen</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/platform-integration/web/embedding-flutter-web"><div><span>Add to a web app</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/debugging"><div><span>Debug embedded Flutter module</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/multiple-flutters"><div><span>Add multiple Flutter instances</span></div></a></li><li class="nav-item"><a class="nav-link" href="/add-to-app/performance"><div><span>Loading sequence and performance</span></div></a></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-29" role="button" aria-expanded="false" aria-controls="sidenav-29"><span>Tools & editors</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-29"><li class="nav-item"><a class="nav-link" href="/tools/android-studio"><div><span>Android Studio & IntelliJ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code"><div><span>Visual Studio Code</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-29-3" role="button" aria-expanded="false" aria-controls="sidenav-29-3"><span>DevTools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-29-3"><li class="nav-item"><a class="nav-link" href="/tools/devtools"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/android-studio"><div><span>Run from Android Studio & IntelliJ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/vscode"><div><span>Run from VS Code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cli"><div><span>Run from command line</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/inspector"><div><span>Flutter inspector</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/legacy-inspector"><div><span>Legacy Flutter inspector</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/performance"><div><span>Performance view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/cpu-profiler"><div><span>CPU Profiler view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/memory"><div><span>Memory view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/console"><div><span>Debug console view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/network"><div><span>Network view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/debugger"><div><span>Debugger</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/logging"><div><span>Logging view</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/app-size"><div><span>App size tool</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/extensions"><div><span>DevTools extensions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/deep-links"><div><span>Validate deep links</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/devtools/release-notes"><div><span>Release notes</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/sdk"><div><span>SDK overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pubspec"><div><span>Flutter's pubspec options</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/flutter-fix"><div><span>Automated fixes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/formatting"><div><span>Code formatting</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-30" role="button" aria-expanded="false" aria-controls="sidenav-30"><span>Flutter concepts</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-30"><li class="nav-item"><a class="nav-link" href="/resources/architectural-overview"><div><span>Architectural overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/inside-flutter"><div><span>Inside Flutter</span></div></a></li><li class="nav-item"><a class="nav-link" href="/ui/layout/constraints"><div><span>Understanding constraints</span></div></a></li><li class="nav-item"><a class="nav-link" href="/testing/build-modes"><div><span>Flutter's build modes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/hot-reload"><div><span>Hot reload</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#sidenav-31" role="button" aria-expanded="false" aria-controls="sidenav-31"><span>Resources</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-31"><li class="nav-item"><a class="nav-link" href="/resources/faq"><div><span>FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/books"><div><span>Books</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/videos"><div><span>Videos</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/courses"><div><span>Courses</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/bootstrap-into-dart"><div><span>Learn Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/support"><div><span>Get support</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-31-8" role="button" aria-expanded="false" aria-controls="sidenav-31-8"><span>Contribute</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-31-8"><li class="nav-item"><a class="nav-link" href="/resources/bug-reports"><div><span>Create useful bug reports</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://github.com/flutter/flutter/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener"><div><span>Contribute to Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/design-docs"><div><span>Discover proposed features</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#sidenav-31-9" role="button" aria-expanded="false" aria-controls="sidenav-31-9"><span>Reference</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="sidenav-31-9"><li class="nav-item"><a class="nav-link" href="/dash"><div><span>Who is Dash?</span></div></a></li><li class="nav-item"><a class="nav-link" href="/reference/widgets"><div><span>Widget index</span></div></a></li><li class="nav-item"><a class="nav-link" href="/reference/flutter-cli"><div><span>flutter CLI</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://api.flutter.dev" target="_blank" rel="noopener"><div><span>API docs</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></li></ul></nav></div><main class="site-content"><div id="site-toc--side" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item"><a class="nav-link" href="#views">Views</a><ul class="nav"><li class="toc-entry nav-item"><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"><a class="nav-link" href="#how-do-i-update-widgets">How do I update widgets?</a></li><li class="toc-entry nav-item"><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"><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"><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"><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"><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"><a class="nav-link" href="#intents">Intents</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><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"><a class="nav-link" href="#async-ui">Async UI</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><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"><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"><a class="nav-link" href="#project-structure-resources">Project structure &amp; resources</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><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"><a class="nav-link" href="#activities-and-fragments">Activities and fragments</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><a class="nav-link" href="#layouts">Layouts</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><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"><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"><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"><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"><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"><a class="nav-link" href="#listviews-adapters">Listviews &amp; adapters</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><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"><a class="nav-link" href="#working-with-text">Working with text</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><a class="nav-link" href="#form-input">Form input</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><a class="nav-link" href="#flutter-plugins">Flutter plugins</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><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"><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"><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"><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"><a class="nav-link" href="#themes">Themes</a><ul class="nav"><li class="toc-entry nav-item"><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"><a class="nav-link" href="#databases-and-local-storage">Databases and local storage</a><ul class="nav"><li class="toc-entry nav-item"><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"><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"><a class="nav-link" href="#debugging">Debugging</a><ul class="nav"><li class="toc-entry nav-item"><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"><a class="nav-link" href="#notifications">Notifications</a><ul class="nav"><li class="toc-entry nav-item"><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><article><header class="site-content__title"><h1 id="document-title">Flutter for Android developers</h1><nav class="breadcrumbs" aria-label="breadcrumb"><ol vocab="https://schema.org/" typeof="BreadcrumbList"><li class="breadcrumb-item" property="itemListElement" typeof="ListItem"><a href="/get-started" property="item" typeof="WebPage"><span property="name">Get started</span></a><meta property="position" content="0"><span class="material-symbols child-icon" aria-hidden="true">chevron_right</span></li><li class="breadcrumb-item" property="itemListElement" typeof="ListItem"><a href="/get-started/flutter-for" property="item" typeof="WebPage"><span property="name">Flutter for</span></a><meta property="position" content="1"><span class="material-symbols child-icon" aria-hidden="true">chevron_right</span></li><li class="breadcrumb-item active" property="itemListElement" typeof="ListItem" aria-current="page"><a href="/get-started/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"><a href="#views">Views</a><ul><li class="toc-entry"><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"><a href="#how-do-i-update-widgets">How do I update widgets?</a></li><li class="toc-entry"><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"><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"><a href="#how-do-i-animate-a-widget">How do I animate a widget?</a></li><li class="toc-entry"><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"><a href="#how-do-i-build-custom-widgets">How do I build custom widgets?</a></li></ul></li><li class="toc-entry"><a href="#intents">Intents</a><ul><li class="toc-entry"><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"><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"><a href="#what-is-the-equivalent-of-startactivityforresult">What is the equivalent of startActivityForResult()?</a></li></ul></li><li class="toc-entry"><a href="#async-ui">Async UI</a><ul><li class="toc-entry"><a href="#what-is-the-equivalent-of-runonuithread-in-flutter">What is the equivalent of runOnUiThread() in Flutter?</a></li><li class="toc-entry"><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"><a href="#what-is-the-equivalent-of-okhttp-on-flutter">What is the equivalent of OkHttp on Flutter?</a></li><li class="toc-entry"><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"><a href="#project-structure-resources">Project structure &amp; resources</a><ul><li class="toc-entry"><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"><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"><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"><a href="#activities-and-fragments">Activities and fragments</a><ul><li class="toc-entry"><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"><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"><a href="#layouts">Layouts</a><ul><li class="toc-entry"><a href="#what-is-the-equivalent-of-a-linearlayout">What is the equivalent of a LinearLayout?</a></li><li class="toc-entry"><a href="#what-is-the-equivalent-of-a-relativelayout">What is the equivalent of a RelativeLayout?</a></li><li class="toc-entry"><a href="#what-is-the-equivalent-of-a-scrollview">What is the equivalent of a ScrollView?</a></li><li class="toc-entry"><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"><a href="#gesture-detection-and-touch-event-handling">Gesture detection and touch event handling</a><ul><li class="toc-entry"><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"><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"><a href="#listviews-adapters">Listviews &amp; adapters</a><ul><li class="toc-entry"><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"><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"><a href="#how-do-i-update-listviews-dynamically">How do I update ListView's dynamically?</a></li></ul></li><li class="toc-entry"><a href="#working-with-text">Working with text</a><ul><li class="toc-entry"><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"><a href="#how-do-i-style-my-text-widgets">How do I style my Text widgets?</a></li></ul></li><li class="toc-entry"><a href="#form-input">Form input</a><ul><li class="toc-entry"><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"><a href="#how-do-i-show-validation-errors">How do I show validation errors?</a></li></ul></li><li class="toc-entry"><a href="#flutter-plugins">Flutter plugins</a><ul><li class="toc-entry"><a href="#how-do-i-access-the-gps-sensor">How do I access the GPS sensor?</a></li><li class="toc-entry"><a href="#how-do-i-access-the-camera">How do I access the camera?</a></li><li class="toc-entry"><a href="#how-do-i-log-in-with-facebook">How do I log in with Facebook?</a></li><li class="toc-entry"><a href="#how-do-i-use-firebase-features">How do I use Firebase features?</a></li><li class="toc-entry"><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"><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"><a href="#themes">Themes</a><ul><li class="toc-entry"><a href="#how-do-i-theme-my-app">How do I theme my app?</a></li></ul></li><li class="toc-entry"><a href="#databases-and-local-storage">Databases and local storage</a><ul><li class="toc-entry"><a href="#how-do-i-access-shared-preferences">How do I access Shared Preferences?</a></li><li class="toc-entry"><a href="#how-do-i-access-sqlite-in-flutter">How do I access SQLite in Flutter?</a></li></ul></li><li class="toc-entry"><a href="#debugging">Debugging</a><ul><li class="toc-entry"><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"><a href="#notifications">Notifications</a><ul><li class="toc-entry"><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>Android has two native user interface systems, Views (XML based) and Jetpack Compose. Some fundamentals are shared so this document will provide value no matter what. However, if you are coming from Jetpack Compose, check out <a href="/get-started/flutter-for/compose-devs">Flutter for Jetpack Compose devs</a> for detailed information about Jetpack Compose and how samples match up to Flutter examples.</p><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-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">(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"> 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">(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"> 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">(onPressed: () {}, 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> <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">(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"> body: </span><span style="color:#0468D7">Center</span><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"> 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">(parent: controller, 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> <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">(title: </span><span style="color:#0468D7">Text</span><span style="color:#222222">(widget.title)),</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">(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"> 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 = referenceBox.</span><span style="color:#6200EE">globalToLocal</span><span style="color:#222222">(</span></span> <span class="line"><span style="color:#222222"> details.globalPosition,</span></span> <span class="line"><span style="color:#222222"> );</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> <span class="line"><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">(onPressed: () {}, 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></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">(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></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> <span class="line"><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> <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 style="color:#BD2314">as</span><span style="color:#0468D7"> String</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="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"> final</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:#BD2314"> final</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> <span class="line"><span style="color:#222222"> (</span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body) </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> List</span><span style="color:#222222">).</span><span style="color:#6200EE">cast</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">Object</span><span style="color:#222222">?>>();</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>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">&#x3C;</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">Object</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">(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"> 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"> final</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:#BD2314"> final</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> <span class="line"><span style="color:#222222"> (</span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body) </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> List</span><span style="color:#222222">).</span><span style="color:#6200EE">cast</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">Object</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:#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"> final</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:#BD2314"> final</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> <span class="line"><span style="color:#222222"> (</span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body) </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> List</span><span style="color:#222222">).</span><span style="color:#6200EE">cast</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">Object</span><span style="color:#222222">?>>();</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>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 style="color:#BD2314">as</span><span style="color:#0468D7"> SendPort</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#222222"> msg =</span></span> <span class="line"><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> <span class="line"><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 style="color:#BD2314">as</span><span style="color:#0468D7"> String</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 style="color:#BD2314">as</span><span style="color:#0468D7"> SendPort</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">(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"> 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 style="color:#BD2314">as</span><span style="color:#0468D7"> SendPort</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#BD2314"> final</span><span style="color:#222222"> msg =</span></span> <span class="line"><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> <span class="line"><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 style="color:#BD2314">as</span><span style="color:#0468D7"> String</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 style="color:#BD2314">as</span><span style="color:#0468D7"> SendPort</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> <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">&#x3C;</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">Object</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">(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"> 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"> final</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:#BD2314"> final</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> <span class="line"><span style="color:#222222"> (</span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(response.body) </span><span style="color:#BD2314">as</span><span style="color:#0468D7"> List</span><span style="color:#222222">).</span><span style="color:#6200EE">cast</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">Map</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">, </span><span style="color:#0468D7">Object</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="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.png</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.png'</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">(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></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">(parent: controller, 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> <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">(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"><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">(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"> 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"> Padding</span><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">), 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">(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"> 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">(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"> 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">(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">), 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></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">(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"> 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">(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">), 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></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">(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"> 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">(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></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">(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"> 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 style="color:#BD2314">const</span><span style="color:#0468D7"> TextSelectionThemeData</span><span style="color:#222222">(</span></span> <span class="line"><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"> ),</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 2025-02-12.</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></article></main></div><footer id="site-footer"><div class="footer-section footer-main"><a class="brand" href="https://flutter.dev"><img src="/assets/images/branding/flutter/logo+text/horizontal/white.svg" alt="Flutter logo" width="164"></a><div class="footer-social-links"><a class="icon-button" href="https://medium.com/flutter" target="_blank" rel="noopener" title="Flutter's Medium blog"><svg><use href="/assets/images/social/medium.svg#medium"></use></svg> </a><a class="icon-button" href="https://youtube.com/@flutterdev" target="_blank" rel="noopener" title="Flutter's YouTube"><svg><use href="/assets/images/social/youtube.svg#youtube"></use></svg> </a><a class="icon-button" href="https://github.com/flutter" target="_blank" rel="noopener" title="Flutter's GitHub"><svg><use href="/assets/images/social/github.svg#github"></use></svg> </a><a class="icon-button" href="https://bsky.app/profile/flutter.dev" target="_blank" rel="noopener" title="Flutter's Bluesky"><svg><use href="/assets/images/social/bluesky.svg#bluesky"></use></svg> </a><a class="icon-button" href="https://twitter.com/FlutterDev" target="_blank" rel="noopener" title="Flutter's X (Twitter)"><svg><use href="/assets/images/social/x.svg#x"></use></svg></a></div></div><div class="footer-section footer-tray"><div class="footer-licenses">Except as otherwise noted, this site is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</a>.</div><div class="footer-utility-links"><ul><li><a href="/tos" title="Terms of use">Terms</a></li><li><a href="/brand" title="Brand usage guidelines">Brand</a></li><li><a href="https://policies.google.com/privacy" target="_blank" rel="noopener" title="Privacy policy">Privacy</a></li><li><a href="/security" title="Security philosophy and practices">Security</a></li></ul></div></div></footer></div><script src="/assets/js/tabs.js?v=4"></script><script src="/assets/js/archive.js?v=4"></script><script src="/assets/js/main.js?v=4"></script></body></html>

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