Hold on, today is the weekend, but I have to go to work…. Ah.. Ah…

I don’t have much to say about Flutter, but GSY is a senior who has a full understanding and deep grasp of Flutter, so I would like to share some of his solutions to Flutter. If you have similar questions, I hope you can find them useful.


After reviewing the answers to all kinds of questions about Flutter during this period, I suddenly found that many people who were new to Flutter had different degrees of misunderstanding about Flutter, and the repeated explanation was a waste of time. Finally, I decided to write an article to make a summary.

It’s a bit long, but I believe it will help you better understand Flutter.

1 the origin of the flutter

Flutter was born out of an internal experiment by the Chrome team. Google’s front end team removed some of the “messy” specifications on the front end and found performance improved by a factor of 20 in benchmark tests.

Therefore, Flutter is born on the front end, and based on the reason for its birth, we can see that Flutter itself does not have much grammatical sugar. As a framework, Flutter is “conservative”, and the Dart language chosen is also conservative. And its programming mode, grammar with a strong front-end color, but it is the first to use in the development of mobile clients.

So when Flutter came out, it faced an awkward situation:

  • For client side native development, declarative development is not used to at first, used to the separation of code and layout (Java \ Kotlin + XML) and imperative object programming, declarative development needs additional learning costs; I also found the nesting of Flutter “disgusting”.

  • In addition to VSCode and the Flutter SDK, there are also native “out of loop” environment variables such as Java, Gradle, Android SDK, XCode, etc. (sometimes encountered with network problems). And the native platform knowledge that Flutter requires is not front-end friendly; I also found the nesting of Flutter “disgusting”.

See? I’m not saying Dart is a learning cost, because Dart is a younger brother to both a JS savvy front-end and a Java\Kotlin\Swift savvy client.

In addition, both the front-end and the client will criticize the nesting of Flutter as “disgusting”. But is nesting a serious problem? We’ll talk about that later.

To sum up, Flutter has a certain threshold and psychological resistance to the entry of the front end or the client end into the pit. Is it necessary for a front-end or client to learn about Flutter?

2 reasons to learn Flutter

In most of my experience with Flutter, a large part of it is actually “forced” to use Flutter. One of the most “powerful” reasons is that I have to start learning about Flutter because my leader or boss requires it: Unless you choose to jump ship and move on.

1. Personal competitiveness

Actually develop the community is very interesting, we often use a technique for a long time, it is easy to think the technology is the fire, because people around are used, while the rest of the frame to be cool, because no one with illusion, especially under the incitement of “media”, “pregnant women effect” is easy to bring on the cognitive misunderstanding.

In the middle of last year, I made a simple data analysis on 53 samples in “Analysis of Cross-platform Framework Access of Domestic Big Manufacturers on Mobile Terminals”. It can be seen that Flutter (19), Weex (17), React-Native (22), Also shown below is a production application of Flutter on a personal phone using libChecker.

To introduce this, Flutter is no longer the niche framework it once was. In the past two years, Flutter has become one of the mainstream cross-platform development frameworks.

So Flutter can really help you find a job, but I don’t recommend learning Flutter from scratch, because Flutter itself is just a cross-platform UI framework.

It is important to understand this sentence because it will help you avoid selling anxiety. Flutter supports mobile, Web and PC applications, but as a UI framework, Flutter mainly helps us to solve the “cross-platform” problem of UI and some business logic. Platform-specific features such as Bluetooth, platform interaction, data storage, packaging and building all depend on native support.

At the present stage, all cross-platform frameworks, including Flutter, React-Native and WeeX, are positioned as UI frameworks. They solve the cross-platform cost of UI business, and their development cannot be without the support of native platform development.

If the native platform is dead, why not? For example, who is talking about cross-Winphone now? Therefore, Flutter and the native platform should be a situation of mutual growth, not the “rhythm party” of “XXX overlords, ### Cool”. Both of them are parasitic and symbiotic. Without the development experience of the corresponding platform, it is difficult to use Flutter “joyfully”.

But now Flutter can actually help your career because it amplifies your business development capabilities and allows you to participate in more platform development, whether it’s a big front-end or KPI. Of course, these React-Native and Uni-apps can also give you, even less for front-end development, so why Flutter?

In fact, one interesting point is that learning to Flutter is equivalent to learning more than 70% of Jetpack Compose for Android native development.

2. Consistency of Flutter

In fact, I personally always recommend the client to learn Flutter, because for the front-end, react-native and Uni-app are indeed more expensive. Of course, it seems that your leaders and bosses don’t think so.

So what are the additional benefits of using Flutter? That is the performance and consistency of Flutter.

Because Flutter is a UI framework, it is truly cross-platform! Because unlike React-Native and Weex, Flutter controls are not rendered by native controls, but by platform-independent rendering capabilities provided by the Flutter Engine. That is, the controls of Flutter are not platform dependent.

To put it simply, native platforms provide a Surface as an artboard, and all that remains is for Flutter to render the corresponding controls, which are eventually packaged into AOT binaries.

So Flutter’s UI controls can be wySIWYG, which is an important development for me personally. Why do you say that? This is where the React-Native comparison comes in.

Because React-native converts JS controls into native controls for rendering, controls in RN rely on native platform controls. Therefore, the differences between native controls in different systems, and the differences in properties and effects of controls in different versions of the same system, This adds up to a large maintenance cost during late development.

During my react-Native development career, this often happened:

  • A debugged style on iOS fails on Android;

  • Styles that work on Android are not supported on iOS;

  • Control effect in iOS platform, in Android has a different display, such as drop-down refresh, Appbar, etc.;

Of course, these problems could eventually be solved by using if else and custom platform controls, but as the project progressed, the result was definitely against my intention to use cross-platform.

The control nature of Flutter ensures that it does not have these problems. I often even develop and test all the interface logic on an iOS emulator without worrying about compatibility on Android. Of course, screen size adaptation is inevitable.

Loosely speaking, Flutter is more like a light game engine like Unity, but it provides 2D controls.

Of course, there is a downside to this implementation of Flutter. The cost and experience of Flutter are magnified when you need to use the platform’s controls for hybrid development, which gives React-Native an inherent advantage.

3. The performance of Flutter

Here are a few misunderstandings:

1. The difference between Debug and release performance of Flutter is huge because of the difference between JIT and AOT.

2. Don’t test performance on emulators, it doesn’t make sense because the Flutter on mobile relies more on the GPU’s capabilities.

3. The mixed development of Flutter will have an impact on performance. For example, in the original Android project, the business logic of a module was changed to Flutter, which will have a great test on performance and memory. This is the negative effect of Flutter independent control rendering and stack management mentioned earlier.

4, the same framework under different people will write different results, generally for ordinary developers, popular framework generally does not bring great performance bottlenecks, but more development capacity leads to project bottlenecks.

How to learn Flutter?

Once you have a quick setup of the environment and a brief understanding of the Flutter API, learning Flutter seems to me to have two core points: responsive development and what’s behind the Widget?

1. Responsive development

Responsive programming is also called declarative programming, which is now the mainstream of front-end development. Of course, it is a trend for client development, such as Jetpack Compose and SwiftUI.

You’d be surprised how similar Jetpack Compose and Flutter are.

What is responsive development? Simply put, you don’t need to manually update the interface. You just need to “declare” the interface through code, and then connect the relationship between the data and the interface. When the data is updated, the interface will be updated.

At the code level, for native development, there is no XML layout in responsive development. The layout is done entirely by code. What you see is what you get, and you don’t need to manipulate interface “objects” to assign and update values.

Here’s an example:

  • In the old days on Android you would write an XML, lay out a TextView, call findViewById to get the object, and call setText to assign the value;

  • Now, in Flutter, you only need to declare a Text Widget and configure data such as data.title to the Text. When the data changes, the Text display also changes.

For Android development, you might think that this is not the same as MVVM DataBinding. In fact, it’s not the same. Here’s an example of why Data Binding mode is not responsive development:

Because Data Binding (in both this library and this programming mode) doesn’t do “declarative UI,” or declarative UI is a stronger Data Binding than Data Binding, for example, in Compose you simply bind string values, You can also use Boolean data to control the presence of interface elements, such as creating another Boolean variable to control the display of one of your text:

Note that instead of setting a setVisibility(GONE) when show is true and then false, the Text() above disappears in the interface code. A declarative UI is one that data binding can’t do: every data change causes an interface update that looks like it’s been closed and restarted and reinitialized with new data.

Compose doesn’t actually reboot the interface, of course. It only refreshes the parts that need to be refreshed, so that its automatic updates can be as efficient as our manual updates.

This is also the case with Flutter. When you use true and false layouts like this, you directly affect the structure of the Widget tree and even the underlying rendering logic. Therefore, as Android developers, you need to get used to this development mode when learning Flutter. “Give up” the idea of saving or holding an interface control to manipulate after retrieving data. In addition, holding a Widget to modify Flutter is mostly meaningless, which is what we’ll talk about next.

2. Behind the Widget

Everything in a Flutter is a Widget. Widgets are immutable. Each Widget state represents a frame.

It is important to understand this statement, and it is also a source of confusion for many developers who start to work with Flutter, because all of the interface displays in Flutter start with widgets at the code level.

The Widget is immutable, which means that it must be rebuilt when the page changes. The fixed state of the Widget represents a still frame. When the screen changes, the corresponding Widget must change.

As an example I often mention, the following code defines a TestWidget that takes the title and count parameters passed in and displays them on Text, and only displays 99 if count is greater than 99.

/// Warnning /// This class is marked as '@immutable' /// but one or more of its instance fields are not final class TestWidget extends StatelessWidget { final String title; int count; TestWidget({this.title, this.count}); @override Widget build(BuildContext context) { this.count = (count > 99) ? 99 : count; return Container( child: new Text("$title $count"), ); }}Copy the code

This code looks fine and works fine, but the compiler will say “This class is marked as ‘@immutable’, “But one or more of its instance fields are not final.” This is because the count member variable in TestWidget does not have a final declaration, leading to ambiguity at the code level.

Since Widget is immutable, every change in Widget causes itself to be rebuilt, meaning that the count member variable in TestWidget is never saved and reused.

As shown above, the count member in the code does not have a final declaration, so the theory is that it can be assigned to the count member twice, giving the illusion that the count member is saved in the TestWidget and used twice. This can easily lead to ambiguity, such as widget.count in some cases. So you need to add the final to see the immutable logic of the Widget.

If you replace the StatelessWidget with a StatefulWidget and put the Build method in State, the count in State can be saved across frames.

class TestWidgetWithState extends StatefulWidget { final String title; TestWidgetWithState({this.title}); @override _TestWidgetState createState() => _TestWidgetState(); } class _TestWidgetState extends State<TestWidgetWithState> { int count; @override Widget build(BuildContext context) { this.count = (count > 99) ? 99 : count; return InkWell( onTap: () { setState(() { count++; }); }, child: Container( child: new Text("${widget.title} $count"), ), ); }}Copy the code

So the most important thing here is to understand the immutable nature of widgets first, and then to know that State allows you to save and restore data across widgets, so why State?

This brings us to another important aspect of Flutter. What is behind the Widget? In fact, the widgets in Flutter are not really controls. In the world of Flutter, the widgets we use most often are more like configuration files. Behind them are the Elements, RenderObject, Layer, and so on that actually “do the work”.

Element, RenderObject, and Layer are the objects that need to be understood.

For a simple example, see the following code, where testUseAll Text is used in three places on the same page, and the code renders properly. If it is a real View, it cannot be used in multiple places on the same page.

In a Flutter setting, widgets are configuration files that tell a Flutter how you want to render. Widgets in a Flutter pass through Element, RenderObject, and even Layer to render. So widgets that are configuration files can be @immutable and can be refactored with every status update.

So back to the original question: is the nesting of Flutter disgusting? Yes, it is true that the configuration of Flutter causes it to be nested, but when you think of widgets as configuration files, you can better organize your code. For example, the Container in Flutter is an abstract configuration template.

By referring to Container, you learn the first step of Flutter to organize code logic.

Also, because widgets don’t actually work, nesting is not actually nesting views. In general, nesting widgets doesn’t cause performance problems because they don’t work, and nesting doesn’t cause a significant performance penalty.

For example, when you write a bunch of widgets that are loaded, the first one will produce an Element, which then holds the Widget and RenderObject.

To put it simply, if the screen changes later on in the Widget are updated to the RenderObject, the State that can be stored across frames in a Flutter is actually held by Element and can be used to store data across widgets.

Each Widget state represents a frame. The “configuration information” represents the current screen. Behind the Widget, there are nested Padding and Align controls. Finally, it is just an “offset calculation” in Canvas.

So it is important to understand that a Widget is not really a View, it is just configuration information. Only by understanding this can you discover the wider continent of Flutter, such as:

  • The control of Flutter was not the real work object until Elemnt.

  • To see how a Widget’s interface works, look at how RenderObejcet is drawn.

  • To see why pages of different stacks or modules don’t interfere with each other, look at the logic of its Layer;

  • Do all widgets have RenderObejcet? What is the mapping between Widget, Elemnt, RenderObejcet, and Layer?

This is what you need to understand and digest to learn about Flutter. Once you understand the complex logic behind the widgets, you will see how simple Flutter is and how easy it is to implement complex widgets. The ability of Canvas to compose a Flutter is really great.

Of course, this part can not be explained in a few words. The third and fourth chapters of my book “Detailed Description of Flutter Development” focus on the content, which is also the main soul of this book. This part of the content will not become obsolete because of the iterations of Flutter version.

The flutter is a frame with a pit

Finally, about the pit of Flutter, in fact, there is no frame without pit. If the frame is perfect, our competitiveness will be weaker and weaker, and the replaceable will be higher.

That’s why android and iOS development were so hot at first, but now client recruiting is coming back to a rational level, as the field matures.

In fact, I’ve always felt that we have no special value in using frameworks, and that solving the problems that frameworks bring is our unique value.

Flutter has its own problems, such as:

  • WebView problems: Due to the unique UI mechanism of Flutter, Flutter needs to be connected to controls such as WebView and MapView in a special way. This also causes technical problems such as performance, keyboard, input box, etc.

  • Image processing and loading: There is no doubt that Flutter is weak in image processing and loading. It is also prone to memory overflow and GPU overflow when loading a single large image or displaying a large list of images. And this part of the problem is particularly troublesome to deal with, if you need to borrow the native platform to solve, you need to use external texture to complete, and this implementation is not low maintenance cost.

  • Mixed development is an unavoidable topic: Because Flutter controls and page stack are separated from the native platform, the result of mixed development will lead to an increase in maintenance cost. Currently, flutter_boost and Flutter_thrio are not able to solve the pain points in mixed development. So this will be a big test for Flutter.

In fact, most of the questions I received about Flutter had nothing to do with Flutter. For example:

  • “Flutter Doctor stuck after running”

  • “Error occurred after flutter Run was run”

  • “Dart version incorrect after flutter pub get runs”

  • “Runtime Gradle error, timeout, etc.”

  • “IOS won’t run on real phones.”

  • “Is there a ready-made control like XXX?”

To be honest, if there are any of these problems, I don’t think this is a problem with Flutter, most of the time it is a problem of looking at logs, documents and the Internet, or even just search engine retrieval technology…

Flutter has its problems, but all things considered, Flutter is the most appropriate UI framework for me at this stage.

The last

It has been a long time since I wrote such a long content, and generally not many people can finish reading such a long content. I just hope that this article can give you a more comprehensive understanding of Flutter, or help you find the direction of Flutter learning. Finally, I can quote a sentence from a certain big man:

“Any technology that can be commercialized on a large scale does not require a high LEVEL of INTELLIGENCE, otherwise it will not scale. Programmers, stop being so confident.”

Review past

The love! Best summary of “Advanced Study Notes on Flutter”, theory and Practice