Flutter Top To Bottom: Hans Muller Dan Field
Flutter Top To Bottom: Hans Muller Dan Field
Flutter Top To Bottom: Hans Muller Dan Field
● Introduction
● Architecture, Components
● Cross Platform, Engine
2
Introduction
What Flutter is, etc
3
Flutter is Google’s UI toolkit for
building beautiful, natively
compiled applications for mobile,
web, and desktop from a single
codebase.
4
After we’re done, find out more at flutter.dev
5
An example of what can be built with Flutter
6
Examples of what the community has built with Flutter
7
Examples of typical Flutter apps
8
What does a Flutter app look like?
9
Confidential + Proprietary
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: HelloWorld()));
}
10
11
A few things you should know at the outset
12
Flutter Origins
13
The “React” Architecture
14
Introduced by FaceBook in 2013
● In an MVC application, it’s about keeping the model and the view in sync
● Initially for web applications, later as a framework for native applications
● For the origin story:
See Pete Hunt’s “React: Rethinking best practices” talk at JSConf.EU
15
The User Interface Appears
16
The Application’s State changes
17
Display List changes cascade
18
This is where things start to get complicated
19
The React Idea
20
The React Implementation
21
Flutter’s React Implementation
22
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: HelloWorld()));
}
23
StatefulWidgets can ask to be rebuilt
24
class HelloWorldState extends State<HelloWorld> {
int count = 0; // The widget's state
@override
Widget build(BuildContext context) {
final TextStyle style = Theme.of(context).textTheme.headline1;
return GestureDetector(
onTap: () {
setState(() { // Ask for HelloWorld to be rebuilt
count += 1; // ... with the updated state
});
},
child: Container(
color: Colors.white,
alignment: Alignment.center,
child: Text('Hello World $count', style: style),
),
);
}
}
25
How is Flutter’s display list updated
26
How is Flutter’s display list updated (continued)
27
How is Flutter’s display list updated (continued)
● Renderers are updated in one pass, starting with the updated element subtree roots
● Renderers are created or updated in place. In place updates happen if:
○ The element’s old widget has the same type as the new one
○ The old widget has the same key as the new one (by default, widget keys are null)
○ Don’t worry about the keys for now
● An updated renderer can mark itself as needing layout or painting
● There are additional passes for layout and painting of the marked renderers
○ Layout is one pass, renderers compute the size and location of each (renderer) child
○ Painting is back to front
28
How is Flutter’s display list layout updated (continued)
● Only subtrees below renderers that were marked as needing layout are processed
● Renderer layout is governed by a simple BoxConstraints type
○ minWidth, maxWidth
○ minHeight, maxHeight
● The entire process is one pass:
○ Constraints are applied top-down
○ Sizes and positions are computed bottom-up
● Parents indicate if they use the child’s size
○ If not, then the “need layout” flag will not propagate upwards
29
How is Flutter’s display list updated (continued)
30
Flutter’s Widgets
31
Flutter emphasizes widget composition
32
Flutter’s API is unlike traditional UI toolkits
● Traditional toolkit base classes, like Android’s View, can get very big
○ Colors and themes
○ Text and icon styles
○ Contents layout, padding, alignment
○ Scrolling
○ Input handling, keyboard focus
○ Lifecycle
○ …
33
Flutter’s API is unlike traditional UI toolkits (continued)
34
class HelloWorld extends StatelessWidget {
@override
Widget build(BuildContext context) {
final TextStyle style = Theme.of(context).textTheme.headline1;
return Center(
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.white),
child: Padding(
padding: EdgeInsets.all(64),
child: DefaultTextStyle(
style: Theme.of(context).textTheme.headline1,
child: Text('Hello World'),
),
),
),
);
}
}
35
36
Flutter’s API is unlike traditional UI toolkits (continued)
● Many traditional toolkits, like Flex or Android, combine code and markup
● Flutter uses code as markup
● Non-leaf widgets have
○ A Widget valued child property
○ List<Widget> valued children properties
37
class HelloWorld extends StatelessWidget {
@override
Widget build(BuildContext context) {
final TextStyle style = Theme.of(context).textTheme.headline1;
return Center(
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.white),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.camera, size: 64, color: Colors.blue),
Text('Hello World', style: style),
Icon(Icons.camera, size: 64, color: Colors.orange),
],
),
),
);
}
}
38
39
Flutter’s “basic” library (nearly 200 widgets)
40
Flutter’s “material” library (about 100 widgets)
41
Flutter’s “cupertino” library (about 30 widgets)
● Components that look and feel like their native iOS counterparts
○ CupertinoActionSheet ○ CupertinoNavigationBar
○ CupertinoTabBar ○ CupertinoScrollbar
○ CupertinoButton ○ CupertinoSlider
○ CupertinoContextMenu ○ CupertinoSlidingSegmentedControl
○ CupertinoDatePicker, CupertinoTimerPicker ○ CupertinoSwitch
○ CupertinoAlertDialog, CupertinoDialog ○ CupertinoTabView
○ CupertinoTextField
42
Thanks for Listening
Find Flutter at:
flutter.dev
flutter.dev/youtube
Hans Muller Dan Field
hansmuller@ dnfield@ @flutterdev
43
Making a Toolkit Cross Platform
Why not the Web Platform?
● Skia: the GPU accelerated 2D graphics engine that is used by Chrome and Android.
○ Abstracts software based, OpenGL, Vulkan, and Metal rendering.
○ Abstracts font rendering.
● Harfbuzz: A glyph shaping library to help with text layout and glyph shaping.
● Dart: A multi-platform, strongly typed, garbage collected language that can be run in JIT mode
or compiled and assembled into native machine code (“AOT” compiled).
○ Dart feels familiar to people who already know Java, C#, or JavaScript.
Flutter’s Core Library: dart:ui
void main() {
window.onBeginFrame = (Duration duration) {
final SceneBuilder builder = SceneBuilder();
final PictureRecorder recorder = PictureRecorder();
final Canvas canvas = Canvas(recorder);
canvas.drawRect(
Rect.fromLTWH(100, 100, 200, 200),
Paint()..color = Color.fromARGB(255, 50, 50, 50));
builder.addPicture(Offset.zero, recorder.endRecording());
● Most* platforms use a shared C++ codebase to manage compositing, rendering, and integration
with the Dart runtime, Skia, Harfbuzz, etc.
● Platforms also provide a specific embedding implementation:
○ iOS/macOS: Objective C (public), Objective C++ (private)
○ Android: Java
○ Linux/Windows: C++
○ Embedder API: C
○ Web: Dart!
The Core of the Engine
● Create a rendering surface for the Shell to work with, e.g. OpenGL, Metal, Vulkan.
● Create/setup threads, provide event loop interop.
● Inform the shell of system events related to application lifecycle or settings.
● Bridge between Flutter’s representation of Semantics with the system Accessibility Services.
● Provide text/pointer input information.
● Host native plugins.
● Produce binaries suitable for use on the platform.
A Minimal Flutter Embedder
● Embedders must link with the core of the engine into a product that can be shipped to their
respective platforms - e.g. a JAR or AAR file for Android, a .framework for iOS, etc.
● They must also be able to load packaged assets from applications, including compiled Dart
binaries and image/font resources for the platform.
● Flutter’s tooling further supports creating end binary packages, such as APK/AAB/IPA programs
for various platforms.
● Just like the Flutter framework makes it easier to use the primitives in dart:ui, the tooling makes
it easier to use the building blocks provided by the Dart SDK and the Engine.
Profiling
● We often focus on frame rate when thinking of performance, but energy usage is critical on
mobile devices.
● Flutter works to be efficient and economical in its usage of CPU and GPU resources.
● Flutter also gives developers fine grained control over every frame:
○ Complicated animations are easier to make with Flutter!
○ But the model requires more work per frame than other simpler animation frameworks.
● Some platforms report energy usage that does not actually match up with battery discharge
rates, which causes confusion for developers.
Binary Size
● Developers may want to use your toolkit for pieces of their application rather than rewriting it
whole.
● Flutter supports incremental adoption via normal platform methods, and significant parts of the
engine embedding code is devoted to making this work nicely.
● When designing bindings between the toolkit and the OS, assume that developers will need to
use them within existing, mature applications.
Find Flutter at:
flutter.dev
flutter.dev/youtube
Hans Muller Dan Field
hansmuller@ dnfield@ @flutterdev