- Flutter i Jetpack Compose comparteixen un model d'IU declaratiu i reactiu, però difereixen en llenguatge, ecosistema i abast de plataforma.
- Compon mapes netament a conceptes de Flutter: components componibles a widgets, llistes Lazy a ListView/GridView, Canvas a CustomPainter i temes a ThemeData.
- Les habilitats natives d'Android (cicle de vida, navegació, recursos, concurrència) es transfereixen directament a Flutter a través de widgets, Navigator, recursos i async/await.
- Per a projectes només per a Android, Compose destaca, mentre que Flutter destaca quan necessiteu una única base de codi per a Android, iOS, web i escriptori.

Si ja et sents còmode escrivint interfícies d'usuari amb Jetpack Compose i et preguntes com de difícil és passar a Flutter, estàs en una posició excel·lent. Ambdues eines són declaratives, reactives i creades per Google, de manera que una gran part del vostre model mental es transmet gairebé un a un. Les principals diferències resideixen en el llenguatge (Kotlin vs Dart), l'estructura del projecte i com cada framework es comunica amb les capes subjacents d'Android (i, en el cas de Flutter, iOS, web i escriptori).
Aquesta guia està escrita específicament per a desenvolupadors de Jetpack Compose que volen entendre Flutter en profunditat, sense artificis de màrqueting. Veureu com els conceptes bàsics es relacionen entre els dos mons: elements componibles vs. widgets, modificadors vs. paràmetres de constructor, dissenys Lazy vs. ListView/GridView, Canvas vs. CustomPainter, Navigation Compose vs. Navigator, remember vs. StatefulWidget i més. També connectarem els vostres antecedents més amplis d'Android (vistes, cicle de vida, recursos, intencions, treball en segon pla) amb els seus equivalents de Flutter perquè la corba d'aprenentatge sembli més un pas lateral que una pujada.
De Jetpack Compose a Flutter: on es transfereixen les teves habilitats
Flutter és el marc de treball d'IU de Google per crear aplicacions multiplataforma utilitzant el llenguatge Dart, mentre que Jetpack Compose és el conjunt d'eines d'IU modern de Google per a Android natiu que utilitza Kotlin. Sota el capó, apunten a diferents temps d'execució, però arquitectònicament comparteixen la mateixa gran idea: descriure la interfície d'usuari com una funció d'estat, deixar que el marc de treball descobreixi quan i com tornar a dibuixar.
A Jetpack Compose es pensa en termes de funcions componibles, modificadors i recomposició; a Flutter es pensa en termes de widgets, paràmetres de constructor i reconstruccions. Malgrat la diferència de noms, el comportament és sorprenentment similar: es crea un arbre d'elements d'IU, cada node és immutable i, quan l'estat canvia, el marc de treball torna a recórrer aquest arbre per produir una interfície actualitzada.
Una diferència clau és que Flutter és multiplataforma per disseny. La mateixa base de codi Dart pot tenir com a objectiu Android, iOS, web, Windows, macOS i Linux. Compose s'està expandint més enllà d'Android (per exemple amb Compose Multiplatform), però la història multidispositiu de Flutter és molt més madura i cohesionada ara mateix, i és precisament per això que molts equips que prioritzen Android la tenen en compte quan volen llançar a iOS o escriptori.
El teu coneixement de la plataforma Android en si mateixa continua sent extremadament valuós en els projectes de Flutter. Mentre que la capa d'IU és purament Dart i widgets, Flutter depèn d'Android (i iOS) per als permisos, la configuració del sistema, les API de la plataforma, les notificacions, el treball en segon pla i moltes altres capacitats, a les quals s'accedeix mitjançant complements i canals de la plataforma. Això vol dir que tota la intuïció que has acumulat sobre com es comporta Android no es malgasta, només mou una capa cap avall.
Model d'IU declaratiu: elements componibles vs. widgets
Tant Jetpack Compose com Flutter implementen un model d'IU declaratiu: es descriu "com" hauria de ser la IU per a un estat determinat, no "com" mutar les vistes pas a pas. En lloc de cridar els configuradors a les vistes, reconstruïu l'arbre quan l'estat canvia i deixeu que el marc de treball faci les diferències i es redibuixi de manera eficient.
A Jetpack Compose, els elements de la interfície d'usuari són funcions componibles anotades amb @Composable, sovint configurat amb un Modifier. Un botó podria ser Button(onClick = ..., modifier = Modifier.padding(16.dp))La cadena de modificadors decora o disposa un element componible sense canviar-ne el tipus subjacent, i Compose utilitza la recomposició per actualitzar només les parts de l'arbre les entrades de les quals han canviat.
A Flutter, els elements de la interfície d'usuari són widgets: objectes Dart simples que descriuen la configuració. També són immutables i estan organitzats en un arbre, però en comptes de passar un modificador, normalment es passen arguments de disseny o d'estil directament a través dels paràmetres del constructor, o bé s'embolica un widget en altres widgets de disseny. Per exemple, es pot escriure Padding(padding: EdgeInsets.all(16), child: ElevatedButton(...)) per aconseguir un resultat similar.
El cicle de vida tant dels elements componibles com dels widgets és intencionadament curt i immutable. Només viuen fins que una nova entrada requereixi que siguin substituïdes; cap de les dues intenta gestionar la seva pròpia vida útil ni mutar-se directament. Això és un canvi conceptual respecte al vell món d'Android View, on les vistes són objectes de llarga durada, reutilitzats i mutats amb el temps, i és per això que la mentalitat de Compose es percep tan natural a Flutter.
Sota el capó, el disseny en ambdós marcs segueix el mateix patró basat en restriccions i impulsat pels pares. El pare es mesura a si mateix, passa restriccions cap avall, els fills trien una mida que respecti aquestes restriccions i el pare posiciona els seus fills. A Flutter veureu que això apareix directament com BoxConstraints; a Compose es gestiona en implementacions de MeasurePolicy. En ambdós casos, els pares poden restringir els fills: els widgets no poden simplement triar la mida o la posició que vulguin.
Estructurar una aplicació: punt d'entrada, bastida i dissenys
A Android amb Compose, el punt d'entrada sol ser un Activity (sovint un ComponentActivity) on truques setContent per allotjar els vostres components. A partir d'aquí, es construeix l'arbre componible, normalment començant amb un MaterialTheme i una superfície o bastida que defineix el vostre disseny d'alt nivell.
A Flutter, el punt d'entrada és un Dart. main funció que crida runApp amb el widget arrel de la teva aplicació. Aquesta arrel és normalment una MaterialApp or WidgetsApp widget, que configura l'encaminament, la temàtica, la localització i el navegador base. La primera "pantalla" que mostreu sovint utilitza un Scaffold widget, que juga un paper molt similar a Scaffold a Material 3 Compose: et proporciona la barra d'aplicacions, el cos, el botó d'acció flotant, els calaixos, etc.
Per a text simple i contingut estàtic, Compose pot ajustar per defecte el contingut (fent coincidir la mida amb el contingut intrínsec), mentre que molts widgets de Flutter ocupen per defecte més espai disponible, tret que estiguin restringits. Per exemple, si col·loqueu un Text componible dins d'una columna, no omplirà automàticament l'amplada. A Flutter, un Text dins d’un Column es pot comportar de manera diferent segons les restriccions del seu pare. Per centrar el contingut a Flutter, sovint embolicareu les coses en un Center widget o utilitzar widgets de disseny com ara Align, Row, Columni Expanded combinat amb les propietats d'alineació.
Els dissenys lineals es mapen gairebé perfectament: Compose té Row i Column, i també ho fa Flutter. A Flutter fas passar els nens per un List<Widget> i controlar l'espaiat i l'alineació amb propietats com ara MainAxisAlignment i CrossAxisAlignmentA Compose, confies en horizontalArrangement, verticalArrangement, horizontalAlignment i verticalAlignmentUna manera útil de pensar-hi: les propietats que acaben en "Disposició" es mapegen a l'eix principal de Flutter, i les que acaben en "Alineació" es mapegen a l'eix transversal.
Quan necessiteu dissenys relatius o superposats, els enfocaments també estan alineats conceptualment. A l'XML d'Android, podeu recórrer a RelativeLayout o una barreja imbricada de LinearLayout i FrameLayoutA Compose, compondries Row, Column i Box (o escriviu un disseny personalitzat). A Flutter, l'analògic és Row, Column i Stack combinat amb fills posicionats i opcions d'alineació. El vostre model mental per organitzar elements entre si es mou gairebé sense canvis.
Botons, entrada i interacció
A Jetpack Compose, crear un botó normalment significa utilitzar Button o una de les seves variants de Material, que sota el Material 3 es resol en una implementació específica com ara FilledTonalButton. Vostè proporciona un onClick lambda i estil opcional, sovint mitjançant paràmetres com ara colors o modificadors per al farciment, l'amplada i l'alineació.
A Flutter, l'equivalent és utilitzar widgets com ara FilledButton, ElevatedButton, TextButton or OutlinedButton. Cadascun pren un onPressed devolució de trucada i una child giny, sovint un Text. Els podeu personalitzar passant-hi un style per ButtonStyle o bé utilitzant una substitució de tema global, que permet ajustar centralment el color, la forma, l'elevació i la mida de tota una família de botons.
Per gestionar gestos, Compose es basa en modificadors com ara Modifier.clickable en molts casos, però també podeu recórrer a detectors de gestos especialitzats quan calgui. Les pressions llargues, els arrossegaments i els gestos personalitzats normalment es componen mitjançant API de modificadors dedicades i fonts d'interacció.
Flutter exposa una explícita GestureDetector un widget que envolta qualsevol cosa que no tingui compatibilitat amb gestos integrada. Ofereix una àmplia gamma de trucades de retorn: onTap, onDoubleTap, onLongPress, onVerticalDragStart, onVerticalDragUpdate, onHorizontalDragEnd i molts altres. Widgets com ElevatedButton ja exposen un onPressed propietat, però per a elements d'IU completament personalitzats podeu utilitzar GestureDetector o widgets de nivell superior com ara InkWell per a la retroalimentació d'ondulació del material.
L'entrada de text a Flutter es gestiona amb TextField or TextFormField, l'estil del qual és paral·lel al de Compose TextField i OutlinedTextField componibles. Configureu pistes, etiquetes, errors i vores mitjançant un InputDecoration similar a com fas servir TextFieldDefaults o paràmetres als camps de text de Compose. Igual que a Compose, normalment es mostren els missatges d'error de manera reactiva canviant l'estat i reconstruint la decoració en lloc de manipular manualment les vistes.
Llistes, quadrícules i contingut desplaçable
Jetpack Compose ofereix dues estratègies principals per a les llistes: simples Column/Row amb iteració per a petites col·leccions, i LazyColumn/LazyRow/LazyVerticalGrid/LazyHorizontalGrid per a llistes grans o dinàmiques. Els contenidors mandrosos només componen allò que és visible, cosa que manté un rendiment alt quan es tracta de milers d'elements.
Flutter segueix el mateix enfocament de petit contra gran però amb diferents widgets. Per a una llista petita que càpiga a la pantalla, només cal utilitzar un Column i mapeu les vostres dades a childrenPer a qualsevol cosa que es desplaci, l'agafes ListView or GridView, amb constructors de generadors que creen fills de manera mandrosa només quan cal.
El patró comú a Flutter és ListView.builder, que reflecteix els elements de la llista mandrosa DSL de Compose. Vostè subministra un itemCount i un itemBuilder callback; Flutter crida aquest constructor amb un índex de 0 a itemCount - 1 sempre que aparegui un element nou. Dins del creador podeu retornar gairebé qualsevol widget, des d'un simple ListTile amb text i icones a files de llista complexes i personalitzades.
Per a les quadrícules, el de Compose LazyVerticalGrid i LazyHorizontalGrid mapa a Flutter's GridView giny. En lloc de passar els recomptes de columnes directament a la quadrícula, Flutter sovint utilitza un delegat com ara SliverGridDelegateWithFixedCrossAxisCount or SliverGridDelegateWithMaxCrossAxisExtent per controlar com es disposen les cel·les. Aquests delegats encapsulen regles com ara "nombre de columnes" o "amplada màxima de cel·la", de manera similar en esperit als paràmetres de mida de la quadrícula que feu servir a Compose.
El comportament de desplaçament també és anàleg en ambdós conjunts d'eines. Les llistes diferides de Compose inclouen el desplaçament integrat; no les emboliqueu en contenidors de desplaçament addicionals. A Flutter, molts widgets de llistes i quadrícules són desplaçables, però per a contingut únic i no repetitiu que s'hauria de desplaçar, podeu utilitzar SingleChildScrollViewLa creació de pàgines desplaçables personalitzades esdevé aleshores una qüestió d'imbricar o compondre fragments per a casos d'ús més avançats.
Patrons d'IU adaptatius i responsius
Compose us ofereix diverses estratègies per al disseny responsiu: dissenys personalitzats, BoxWithConstraints, WindowSizeClass i la biblioteca adaptativa Material 3. Això et permet canviar la composició en funció de l'espai disponible, la postura i la categoria del dispositiu, i pots combinar-les segons la complexitat del projecte.
Flutter no intenta replicar aquestes API directament, però la idea subjacent és la mateixa: inspeccionar les restriccions i les característiques de la pantalla i, a continuació, ramificar el disseny. Les dues eines principals són LayoutBuilder i MediaQuery. LayoutBuilder passa BoxConstraints cap avall per poder intercanviar o reorganitzar els widgets per sobre d'una determinada amplada o alçada. MediaQuery exposa la mida de la pantalla, l'orientació, el farciment i la densitat de píxels per a punts d'interrupció d'alt nivell.
En lloc d'aspirar a una correspondència biunívoca entre les solucions adaptatives de Compose i les de Flutter, és més eficaç pensar en termes dels vostres requisits de disseny. Un cop sàpigues com s'ha d'adaptar la teva interfície d'usuari a telèfons, tauletes i ordinadors d'escriptori, pots expressar aquesta lògica mitjançant Compose WindowSizeClass i dissenys adaptatius o la ramificació basada en restriccions i mitjans de Flutter. El mateix pensament de disseny: API diferents.
Gestió d'estats: remember vs StatefulWidget i més enllà
Jetpack Compose emmagatzema l'estat efímer de la interfície d'usuari mitjançant remember i titulars estatals com mutableStateOf, sovint combinat amb ViewModel i components d'arquitectura per a un estat de vida més llarga. Quan l'estat canvia, es produeix una recomposició i els components rellevants obtenen nous valors.
La història d'estats de baix nivell de Flutter gira al voltant de StatefulWidget i els seus associats State objecte. Defineixes un widget que vol mantenir l'estat estenent StatefulWidget, implementeu-ne un altre per separat State<MyWidget> classe per emmagatzemar camps mutables. Sempre que actualitzeu aquests camps, crideu setState(), que marca aquesta part de l'arbre de widgets com a bruta i activa una reconstrucció. En aquest nivell és molt similar a emmagatzemar l'estat de Compose amb remember i invalidant els elements componibles quan els valors canvien.
Per a aplicacions més complexes, Flutter es basa en gran mesura en patrons comunitaris i de primera part: Provider, Riverpod, Bloc, botigues d'estil Redux i més. Aquests actuen com a anàlegs de les piles d'arquitectura d'Android: ViewModel + LiveData/Flow + repositoris en projectes de Compose. Centralitzen la lògica empresarial i exposen fluxos reactius de dades que impulsen les reconstruccions de widgets. Des d'un context de Compose, trobareu molts d'aquests patrons familiars fins i tot si les API són diferents.
Un punt que sovint sorprèn els desenvolupadors d'Android és que tant els widgets sense estat com els amb estat de Flutter es reconstrueixen amb freqüència, potencialment cada fotograma durant les animacions. La distinció no rau en la freqüència de reconstrucció, sinó en on s'emmagatzema l'estat mutable: StatefulWidget et dóna un company State objecte que sobreviu a les reconstruccions, de manera semblant a com remember permet que els valors sobrevisquin a la recomposició a Compose.
Dibuix, animació i poliment visual
Si alguna vegada has treballat directament amb Android Canvas i Drawable, Compose's Canvas componible probablement semblava senzill. Proporciona una manera declarativa de dibuixar formes, imatges i text a Kotlin, amagant gran part de la cerimònia imperativa de les vistes personalitzades tradicionals.
Flutter exposa una superfície de dibuix similar a través de la Canvas API, a la qual s'accedeix mitjançant CustomPaint i CustomPainter. Implementes un CustomPainter classe on substituïu la paint mètode per dibuixar sobre el llenç utilitzant Paint objectes, camins, transformacions, etc. A continuació, adjunteu aquest pintor a un CustomPaint widget. Tant Compose com Flutter es basen en el motor Skia, de manera que les primitives (línies, camins, shaders) semblen molt familiars a partir del renderitzat 2D d'Android.
Per a les animacions, Flutter es basa en un sistema d'animació explícit construït al voltant de AnimationController, Animation<T> i preadolescents, a més d'un ric conjunt de widgets animats. Instancies un controlador (normalment amb SingleTickerProviderStateMixin per a vsync), defineix CurvedAnimations o Tweens que assignin el progrés 0-1 als valors del domini i després els connecten a widgets com ara FadeTransition, ScaleTransition, AnimatedBuilder o widgets implícits com ara AnimatedContainerEl sistema d'animació també exposa AnimationStatus retrollamades per reaccionar a l'inici, la finalització o la reversió.
Les API d'animació de Jetpack Compose són declaratives de dalt a baix, amb funcions com ara animate*AsState, transicions i visibilitat animada. En lloc de gestionar els controladors manualment en la majoria dels casos habituals, descriviu els estats de destinació i el marc de treball impulsa la interpolació al llarg del temps. Quan necessiteu un control més personalitzat, encara teniu accés a primitives de baix nivell, però la ruta habitual és més concisa que l'XML clàssic d'Android o el codi d'animació imperativa.
Conceptualment, utilitzeu els dos conjunts d'eines de la mateixa manera: manteniu els widgets/composables lleugers i purs, introduïu valors variables en el temps a través d'ells i deixeu que el marc de treball gestioni la interpolació i la invalidació. Com a desenvolupador de Compose, l'explicitat addicional de Flutter AnimationController Pot semblar una mica antiquat al principi, però et dóna un control molt precís sobre el temps, les corbes i l'orquestració.
Estils, temes, fonts i recursos
Les aplicacions modernes viuen o moren amb el poliment, per la qual cosa tant Flutter com Compose posen molt d'èmfasi en la temàtica i l'estil. Usos de la composició MaterialTheme amb esquemes de colors, tipografia i definicions de formes, i podeu imbricar temes per anul·lar valors dels subarbres, incloent-hi forçar superfícies clares o fosques per a regions específiques.
A Flutter, l'equivalent és ThemeData passat a MaterialApp or Theme ginys. Defineixes els colors primaris, la brillantor, la tipografia i els temes específics dels components com ara elevatedButtonTheme, textButtonTheme, appBarTheme i més. Podeu sobreescriure temes localment embolicant subarbres dins Theme widgets que copien el camp principal i modifiquen certs camps. El mode clar i fosc es pot activar o desactivar a nivell d'aplicació proporcionant theme i darkTheme i controlant themeMode.
L'estil de text és un territori familiar: a Compose, o bé passeu propietats simples directament a Text o subministrar un TextStyle objecte. Flutter reflecteix això amb un Text widget que accepta un TextStyle mitjançant la seva style paràmetre. TextStyle cobreix la família de fonts, la mida, el gruix, l'espaiat de les lletres, l'alçada de les línies, la decoració i més. Podeu definir temes de text globals a ThemeData.textTheme i referenciar-los a tot arreu, tal com faries servir la tipografia de MaterialTheme a Composar.
Les fonts i les imatges es gestionen a través d'actius en lloc dels tradicionals d'Android. /res arbre de directoris. Flutter no imposa un disseny de carpeta específic; declares els recursos en pubspec.yaml i després fer-hi referència des del codi. Les imatges normalment es carreguen amb Image.asset(), que resol el contingut de densitat correcte en funció de devicePixelRatioEls píxels lògics tenen el mateix paper que dp a Android, eliminant la densitat física de píxels.
Per a fonts personalitzades, Compose us permet empaquetar recursos de fonts o obtenir-los en temps d'execució mitjançant proveïdors com ara Google Fonts i després connectar-los a FontFamily i tipografia. Flutter utilitza gairebé el mateix patró: col·loca els fitxers de fonts en una carpeta d'actius, llista'ls a pubspec.yamli, a continuació, feu referència a la família de fonts pel seu nom a TextStyleSi voleu fonts recuperades en temps d'execució, hi ha una font popular google_fonts connector que exposa funcions de Dart que porten noms de fonts, p. ex. GoogleFonts.robotoTextTheme()—per connectar-los ràpidament al vostre tema.
Ambdós ecosistemes tracten les cadenes i la localització com a preocupacions de primera classe, tot i que Flutter no té un equivalent directe als recursos de cadenes XML d'Android. En comptes d'això, la millor pràctica és mantenir les traduccions a .arb fitxers i connectar-los amb la cadena d'eines de localització de Flutter. L'accés es produeix a través de classes Dart generades, de manera més o menys anàloga a l'ús R.string identificadors en el codi d'Android.
Conceptes de la plataforma Android a través de la lent de Flutter
Més enllà de la interfície d'usuari, una de les preguntes més importants que tenen els desenvolupadors de Compose és com els seus coneixements d'Android s'adapten a l'arquitectura de Flutter. Afortunadament, moltes de les idees principals (activitats, cicle de vida, intencions, treball en segon pla, recursos, treball en xarxa) tenen contraparts clares, fins i tot si l'API superficial sembla diferent.
A Android, Activity i Fragment són les pantalles i contenidors principals; a Flutter tot és un widget i la navegació es fa a través de Navigator i Route objectes. Una ruta correspon aproximadament a una activitat o fragment, però normalment només hi ha un únic allotjament. Activity a Android que incorpora el motor Flutter. Inseriu i mostreu rutes a la pila del Navigator, ja sigui mitjançant rutes amb nom definides a MaterialApp o mitjançant la construcció directa PageRoute casos com MaterialPageRoute.
Les retrorel·leccions del cicle de vida d'Android (onCreate, onStart, onResume, etc.) no tenen ganxos un a un al codi Flutter, però podeu observar el cicle de vida de l'aplicació amb WidgetsBindingObserver. Exposa estats com resumed, inactive, paused i detached, que corresponen aproximadament a les fases visible, en segon pla i destruïda d'Android. Quan realment necessiteu hooks de cicle de vida de baix nivell per a la gestió de recursos, normalment els implementeu al costat natiu d'Android a FlutterActivity o un complement, que no és al Dart.
Les intencions tenen dues funcions a Android: la navegació dins de l'aplicació i la comunicació entre aplicacions. Com s'ha esmentat, Flutter no té una API de navegació basada en intencions: Navigator la substitueix completament dins del món Dart. Per a tasques entre aplicacions (iniciar la càmera, el selector de fitxers, la gestió de les intencions de compartir), generalment s'utilitzen complements que encapsulen les crides necessàries per a Android (i iOS). Si no existeix cap complement, podeu escriure'n un de propi mitjançant MethodChannels per comunicar-se entre Dart i el codi natiu, reenviant les intencions i els resultats com a missatges.
La teva comprensió del treball en segon pla i del threading també es transfereix, però les primitives tenen un aspecte diferent. Android t'empenta a moure les E/S de xarxa i disc fora del fil principal mitjançant coroutines, AsyncTask (heretat), WorkManager, JobScheduler, RxJava, etc. Dart, en canvi, utilitza un bucle d'esdeveniments d'un sol fil per aïllat, amb async/await per a E/S i aïllats separats per a treball amb molta CPU. Per a qualsevol cosa vinculada a E/S, només cal marcar les funcions. async, await l'operació i deixa que el bucle d'esdeveniments mantingui la interfície d'usuari responsiva; per a tasques pesades de la CPU, s'inicia un aïllat i es comunica mitjançant el pas de missatges en lloc de memòria compartida.
Pel que fa a les xarxes, la popularitat de Flutter http El paquet juga un paper similar a OkHttp + Retrofit per a casos d'ús bàsics. Amaga gran part del treball de sòcols de baix nivell i s'integra naturalment amb async/await. Per a necessitats complexes, podeu optar per paquets com ara dio, però el patró fonamental roman: fer una crida asíncrona, esperar el resultat, actualitzar l'estat amb setState() o el gestor d'estat que hàgiu triat i reconstruïu els widgets afectats.
Complements, emmagatzematge, Firebase i eines
A Android esteu acostumats a declarar dependències a Gradle; a Flutter les declareu a pubspec.yaml i obtenir-los de pub.dev. Els fitxers Gradle sota el android/ La carpeta d'un projecte de Flutter serveix principalment per a integracions específiques de la plataforma o quan necessiteu biblioteques natives personalitzades; el desenvolupament d'aplicacions diàries es manté al món de Dart.
Les preferències compartides i SQLite també tenen equivalents prefabricats. On Android ofereix SharedPreferences per a l'emmagatzematge de valor-clau petit i SQLite (o Room) per a dades estructurades, Flutter encapsula aquests mitjançant complements com ara shared_preferences i sqfliteAquests complements unifiquen el comportament d'Android i iOS, de manera que podeu utilitzar una única API de Dart independentment de la plataforma, tot confiant en les implementacions natives subjacents.
La integració de Firebase és igualment senzilla i de primera classe. La majoria dels serveis de Firebase (Authentication, Firestore, Realtime Database, Cloud Messaging, Analytics, Remote Config i més) tenen complements oficials de Flutter mantinguts pels equips de Firebase i Flutter. Reflecteixen el model conceptual dels SDK de Firebase d'Android però amb API idiomàtiques de Dart. Per a funcions més específiques de Firebase que no es tracten directament, hi ha un ecosistema saludable de complements de tercers a pub.dev.
Per a la depuració i la creació de perfils, el conjunt DevTools de Flutter us ofereix una rica caixa d'eines directament comparable al perfilador i a l'inspector de disseny d'Android Studio. Podeu inspeccionar l'arbre de widgets, fer un seguiment de les reconstruccions, observar les assignacions de memòria, diagnosticar fuites i fragmentacions i analitzar el codi Dart pas a pas. Combinat amb la compatibilitat amb l'IDE a Android Studio i VS Code, la recàrrega en calent i el reinici en calent, el cicle de retroalimentació en el desenvolupament de Flutter sembla almenys tan ajustat (i sovint més ajustat) que el que esteu acostumats amb Compose.
Les notificacions push, una altra preocupació comuna d'Android, es gestionen a Flutter mitjançant complements com ara firebase_messaging. En l'interior, aquests elements es comuniquen amb Firebase Cloud Messaging i els marcs de notificació natius d'Android i iOS, però la lògica de l'aplicació resideix en una API Dart unificada. La configuració i els comportaments específics de la plataforma (com ara els canals de notificació a Android) continuen sent importants, i la vostra experiència existent amb aquests detalls de la plataforma continua sent molt rellevant.
Fins i tot els widgets de la pantalla d'inici a Android, que no es poden implementar únicament a Flutter, sí que es poden integrar amb el codi de Flutter. Normalment els creeu amb Jetpack Glance o dissenys XML i després feu servir un paquet com ara home_widget per comunicar-vos amb la vostra aplicació Flutter, compartir dades i fins i tot incrustar la interfície d'usuari rasteritzada de Flutter com una imatge dins del widget natiu. Aquest enfocament híbrid us permet mantenir la vostra experiència principal a Flutter respectant alhora les restriccions de la plataforma.
Si mirem tots aquests paral·lelismes, un desenvolupador de Jetpack Compose que entra a Flutter no comença de zero. La teva comprensió de la interfície d'usuari declarativa, el cicle de vida d'Android, la navegació, l'estat, els recursos i el treball asíncron s'adapta de manera molt natural al món de Flutter; el que més canvia són els noms, l'idioma (Dart) i la mentalitat multiplataforma. Un cop internalitzes els widgets i el Navigator com a conceptes fonamentals, la resta de la pila tendeix a encaixar força ràpidament.