First Glance at Flutter from an Android Native App Developer
30 Jan 2019I made my decision to try Flutter last December after I saw the demo App "[The History of Everything](https://medium.com/2dimensions/the-history-of-everything-981d989e1b45)" at watching the Flutter 1.0 released video on YouTube, the animation was amazing, I am so touched. As an Android App developer with several years of experience, I am most interested in two questions: - How can Flutter simplify development and make developers' lives easy? - Are there mature Android App solutions that are Flutter-equivalent? The most effective way to learn is coding. So I started to convert few pages of an Android App I am working on to Flutter. The App is a typical List - Detail App contains several key points: # Login Page # List Page # Detail Page +---------------+ +---------------+ +---------------+ | | |[Tab1]2.3[Tab4]| | Image | | [Logo] | |---------------| | Title | | | | item0 | | SubTitle | | [ name ] | => | item1 | => | Body......... | | [ password] | | . | | ............. | | | | . | | | | Login | | . | | | | | | item(n) | | | +---------------+ +---------------+ +---------------+ During this process, I learned a couple of things: - how to build a screen. - how to build a tab navigation view. - how to build a list view. - how to navigate and pass data between screens. - how to restore data during screen rotation. - how to make http request. The following screenshot is the login page which is written in Flutter runs on both iOS and Android: ![](Flutter-eb2b6ba2-efd8-4c34-a45c-932beea5d3cc.png) > BTW: Flutter society provides a lot of resources to learn, the official docs, demo Apps, YouTube channel, Medium articles. I will attach them at the end of this article. ## How to Build a Screen: Screens are Just Widgets ---- As an Android developer, we might have the same experience in development: - (phase 1) Use Activity as a screen at the very beginning; - (phase 2) Then use Fragment as a screen, Activity is just used to host Fragments. We might also struggle with the 2 LifeCycles of Fragment, the nested Fragments backstack, the screen rotation, the navigation between Fragments and Activities. Fortunately we have tools to simplify these problems, like ViewModel, LiveData, Data-binding, Navigation Graph & Controller, etc. Flutter, as a new thing, seems to have no such historical burdens. Flutter claims that > Everything’s a Widget [https://flutter.io/docs/resources/technical-overview#everythings-a-widget](https://flutter.io/docs/resources/technical-overview#everythings-a-widget) **So does Screen**. The following codes snippet builds a simple screen which contains an ActionBar and a Text. The full code contains a `StatefulWidget` which maintains state that might change during the lifetime of the widget, the state won't lost when rotate screen. ```dart Scaffold( appBar: AppBar( title: Text('Welcome to Flutter'), ), body: Center( child: Text('Hello Flutter'), ) ) ``` ## UI as Code: All in One Place ---- You might have realized that to build a screen all by codes is totally different from using XML & visual designer tools. Then you probably questioned how can we build a complicated screen without XML & visual designer tools? It happens to me as well at the very beginning but after writing few pages it has changed my mind and I start to like it because the view logic is all in one place instead of multiple places like Fragment, BindingAdapter, Layout xml, etc. However, All in One Place means a lot of UI codes and might be deeply nested syntax: ```dart ) ]), )) ], ), ), ], ), )); } } ``` But we can get rid of the nested syntax if we follow some rules: > (1). Name subexpressions instead of `return A(B(C(D(), E())), F())`. This turns the widget tree inside out, syntactically. (2). Extract some meaningful pieces… Pieces? Widgets! Flutter widgets are all about composition and reuse. Further reading [Out of Depth with Flutter by Mikkel Ravn](https://medium.com/flutter-io/out-of-depth-with-flutter-f683c29305a8) ## How to Navigate and Pass Data Between Screens ---- In Flutter, **Screens are Just Widgets,** we can just simply pass data to the constructor of the destination widget: ```dart // https://flutter.io/docs/cookbook/navigation/passing-data Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen(todo: todos[index]), ), ); ``` Just a few lines of codes, that's it, fairly straightforward. No Intent, no Fragment Arguments, no Parcelable, no startActivity, no fragmentTransaction, no need to know so much details behind Activity and Fragment. ## How to Build a List View ---- ```dart // https://flutter.io/docs/cookbook/lists/long-lists ListView.builder( itemCount: items.length, itemBuilder: (context, index) { return ListTile( title: Text('${items[index]}'), ); }, ); ``` Just a few lines of codes, no adapter, no item view-holder, no attaching adapter to list view. Further reading: [Flutter ListView and ScrollPhysics: A Detailed Look — Exploring the ListView Widget and its Features in Depth](https://medium.com/flutter-community/flutter-listview-and-scrollphysics-a-detailed-look-7f0912df2754) ## How to Build a Tab Navigation ---- It's quite easy to implement tab navigation in both Material and Cupertino, just simply create the tabs and content for each tab, then set to TabController widget. Further reading [Working with Tabs](https://flutter.io/docs/cookbook/design/tabs) ## Http & Async ---- It's the common practice to use Retrofit + Gson/Moshi + Data Class + Rx/Coroutines to implement API in nowadays. Are there any equivalents in Flutter? - Json serialization: Flutter provide two ways to serialize Json: manually using [dart:convert](https://flutter.io/docs/development/data-and-backend/json#serializing-json-manually-using-dartconvert) lib, or automatically using code generation libraries [json_serializable](https://pub.dartlang.org/packages/json_serializable). Further reading: [JSON and serialization](https://flutter.io/docs/development/data-and-backend/json#creating-model-classes-the-json_serializable-way) - Fetch data from remote: Flutter provide `http` package for this work. Further reading: [Fetch data from the internet](https://flutter.io/docs/cookbook/networking/fetch-data). The following codes snippet shows how I implement the login API in Flutter: ```dart /// api.dart ////////////////////////////////////////////////////////////////// abstract class Api { Future