Share
Embed
Droidcon SF 2017: Building Modern Cross Platform Apps with Flutter
Link to video - https://www.youtube.com/watch?v=GJyYv58eWOU
In this talk, you will learn about getting started with Flutter - a framework that helps you build modern 60 fps mobile apps for iOS and Android. Flutter uses Dart for its development but prior knowledge or use of Dart is not required to attend this talk. We will look at the various features Flutter provides including topics like building layouts with material design, debugging and more.
vinaygaba
November 06, 2017
Transcript
103 slides
-
What is Flutter ? Open source SDK for building cross-platform
apps by Google Support for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool -
What is Flutter ? Open source SDK for building cross-platform
apps by Google Support for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool -
What is Flutter ? Open source SDK for building cross-platform
apps by Google Support for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool -
What is Flutter ? Open source SDK for building cross-platform
apps by Google Support for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool -
What is Flutter ? Open source SDK for building cross-platform
apps by Google Support for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool -
What is Flutter ? Open source SDK for building cross-platform
apps by Google Support for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool -
Open source SDK for building cross-platform apps by Google Support
for Android & iOS Designed keeping both developers and designers in mind Allows building beautiful 60 FPS apps. Designed for speed and is an excellent prototyping tool What is Flutter ? -
But how is it different ? Uses neither WebView nor
OEM widgets that’s shipped with a device SDK is shipped with the app Uses its own high-performance rendering engine to draw widgets Flutter implements most of its system in Dart -
Uses neither WebView nor OEM widgets that’s shipped with a
device SDK is shipped with the app Uses its own high-performance rendering engine to draw widgets Flutter implements most of its system in Dart But how is it different ? -
Uses neither WebView nor OEM widgets that’s shipped with a
device SDK is shipped with the app Uses its own high-performance rendering engine to draw widgets Flutter implements most of its system in Dart But how is it different ? -
But how is it different ? Uses neither WebView nor
OEM widgets that’s shipped with a device SDK is shipped with the app Uses its own high-performance rendering engine to draw widgets Flutter implements most of its system in Dart -
But how is it different ? Uses neither WebView nor
OEM widgets that’s shipped with a device SDK is shipped with the app Uses its own high-performance rendering engine to draw widgets Flutter implements most of its system in Dart -
But how is it different ? Uses neither WebView nor
OEM widgets that’s shipped with a device SDK is shipped with the app Uses its own high-performance rendering engine to draw widgets Flutter implements most of its system in Dart -
Flutter Widget Framework Inspired from React Building blocks of UI
are widgets. Composition over inheritance Everything is a widget. Even the app is a widget Widgets in Flutter are immutable -
Flutter Widget Framework Inspired from React Building blocks of UI
are widgets. Composition over inheritance Everything is a widget. Even the app is a widget Widgets in Flutter are immutable -
Flutter Widget Framework Inspired from React Building blocks of UI
are widgets. Composition over inheritance Everything is a widget. Even the app is a widget Widgets in Flutter are immutable -
Flutter Widget Framework Inspired from React Building blocks of UI
are widgets. Composition over inheritance Everything is a widget. Even the app is a widget Widgets in Flutter are immutable -
Flutter Widget Framework Inspired from React Building blocks of UI
are widgets. Composition over inheritance Everything is a widget. Even the app is a widget Widgets in Flutter are immutable -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”)
) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”,
textDirection: TextDirection.ltr) ) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”,
textDirection: TextDirection.ltr) ) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
void main() { runApp( new HelloWorldApp( textToDisplay: new Text("Hello World”,
textDirection: TextDirection.ltr) ) ); } class HelloWorldApp extends StatelessWidget { HelloWorldApp({this.textToDisplay}); final Text textToDisplay; @override Widget build(BuildContext context) { return new Center( child: textToDisplay, ); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Container(); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Container(); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Container(); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar(), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar(), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton(), body: new Container(), ); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton( child: new Icon(Icons.add_comment, color: Colors.white), onPressed: null), body: new Container(), ); } } class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton( child: new Icon(Icons.add_comment, color: Colors.white), onPressed: null), body: new Container(), ); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton( child: new Icon(Icons.add_comment, color: Colors.white), onPressed: null), body: new Container(), ); } } -
class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {
return new Scaffold( appBar: new AppBar( leading: new Icon(Icons.menu), title: new Text("Inbox"), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search, color: Colors.white), onPressed: null) ], ), floatingActionButton: new FloatingActionButton( child: new Icon(Icons.add_comment, color: Colors.white), onPressed: null), body: new Container(), ); } } -
class Email { const Email( {this.sender, this.subject, this.emailBody, this.timeStamp}); final
String sender; final String subject; final String emailBody; final String timeStamp; } List<Email> _getInboxEmails() { return <Email>[ new Email( sender: "[email protected]", subject: "Email Subject", emailBody: "Thanks for nothing!", timeStamp: "Oct 13"), new Email(...), . . ]; } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox(), theme: new
ThemeData( primaryColor: Colors.red, accentColor: Colors.red, ) ) ); class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold(...); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox( emails: _getInboxEmails()
), theme: new ThemeData( primaryColor: Colors.red, accentColor: Colors.red, ) ) ); class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override Widget build(BuildContext context) { return new Scaffold(...); } } runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox( emails: _getInboxEmails() ), theme: new ThemeData( primaryColor: Colors.red, accentColor: Colors.red, ) ) ); class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override Widget build(BuildContext context) { return new Scaffold(...); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox( emails: _getInboxEmails()
), theme: new ThemeData( primaryColor: Colors.red, accentColor: Colors.red, ) ) ); class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override Widget build(BuildContext context) { return new Scaffold(...); } } class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override Widget build(BuildContext context) { return new Scaffold(...); } } -
runApp( new MaterialApp( title: 'Gmail', home: new GmailInbox( emails: _getInboxEmails()
), theme: new ThemeData( primaryColor: Colors.red, accentColor: Colors.red, ) ) ); class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override Widget build(BuildContext context) { return new Scaffold(...); } } -
class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override
Widget build(BuildContext context) { return new Scaffold(...); } } -
class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override
Widget build(BuildContext context) { return new Scaffold(...); } } -
class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override
Widget build(BuildContext context) { return new Scaffold(...); } } -
class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override
Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(...), floatingActionButton: new FloatingActionButton(...), body: new Container()) ); } } -
class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override
Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(...), floatingActionButton: new FloatingActionButton(...), body: new ListView( padding: new EdgeInsets.symmetric(vertical: 8.0), children: emails.map((Email email) { return new GmailListItem( email: email ); }).toList()) ); } } class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(...), floatingActionButton: new FloatingActionButton(...), body: new ListView( padding: new EdgeInsets.symmetric(vertical: 8.0), children: emails.map((Email email) { return new GmailListItem( email: email ); }).toList()) ); } } -
class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override
Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar(...), floatingActionButton: new FloatingActionButton(...), body: new ListView( padding: new EdgeInsets.symmetric(vertical: 8.0), children: emails.map((Email email) { return new GmailListItem( email: email ); }).toList()) ); } } -
class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email =
email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } -
class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email =
email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } -
class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email =
email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } -
class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email =
email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } -
class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email =
email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email = email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } -
class GmailListItem extends StatelessWidget { GmailListItem({Email email}) : email =
email, super(key: new ObjectKey(email)); final Email email; @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } } -
@override Widget build(BuildContext context) { return new Row( children: <Widget>[
new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } -
@override Widget build(BuildContext context) { return new Row( children: <Widget>[
new Container(), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } -
@override Widget build(BuildContext context) { return new Row( children: <Widget>[
new Container( child: new CircleAvatar( child: new Text(email.sender[0].toUpperCase()), backgroundColor: _getRandomColor()), padding: new EdgeInsets.all(15.0), ), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } -
new Container( child: new Column( children: <Widget>[ new Row(), new
Text(), new Text() ], ), ) @override Widget build(BuildContext context) { return new Row( children: <Widget>[ new Container( child: new CircleAvatar( child: new Text(email.sender[0].toUpperCase()), backgroundColor: _getRandomColor()), padding: new EdgeInsets.all(15.0), ), new Container( child: new Column( children: <Widget>[ new Row(), new Text(), new Text() ], ), ) ] ); } -
new Container( child: new Column( children: <Widget>[ new Row(), new
Text(), new Text() ], ), ) -
new Container( child: new Column( children: <Widget>[ new Row(), new
Text(), new Text() ], ), ) -
new Container( child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ new
Row(), new Text(email.subject, maxLines: 1, overflow: TextOverflow.ellipsis, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 14.0)), new Text(email.emailBody, maxLines: 1, overflow: TextOverflow.ellipsis, style: new TextStyle(color: Colors.grey, fontSize: 14.0)) ], ), ) -
new Container( child: new Column( ... children: <Widget>[ new Row(
children: <Widget>[ new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) -
new Container( child: new Column( ... children: <Widget>[ new Row(
children: <Widget>[ new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) -
new Container( child: new Column( ... children: <Widget>[ new Row(
children: <Widget>[ new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) -
new Container( child: new Column( ... children: <Widget>[ new Row(
children: <Widget>[ new Expanded( child: new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)) ), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) new Container( child: new Column( ... children: <Widget>[ new Row( children: <Widget>[ new Expanded( child: new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)) ), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) -
new Container( child: new Column( ... children: <Widget>[ new Row(
children: <Widget>[ new Expanded( child: new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)) ), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) -
new Container( child: new Column( ... children: <Widget>[ new Row(
children: <Widget>[ new Expanded( child: new Text(email.sender, style: new TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16.0)) ), new Text(email.timeStamp, style: new TextStyle( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12.0)) ] ), new Text(...), new Text(...) ], ), ) -
What Else ? Unit, Integration & Widget Testing ! Animations
Accessing Platform Specific Features Great Tooling (Dart Analyzer, Render Tree Dumps, Perf Overlays)