Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Droidcon SF 2017: Building Modern Cross Platfor...

vinaygaba
November 06, 2017

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
Tweet

More Decks by vinaygaba

Other Decks in Technology

Transcript

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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 ?
  8. 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
  9. 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 ?
  10. 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 ?
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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, ); } }
  20. 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, ); } }
  21. 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, ); } }
  22. 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, ); } }
  23. 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, ); } }
  24. 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, ); } }
  25. 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, ); } }
  26. 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, ); } }
  27. 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, ); } }
  28. 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, ); } }
  29. 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(); } }
  30. 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(); } }
  31. 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(); } }
  32. 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(); } }
  33. 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(); } }
  34. 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(); } }
  35. 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(); } }
  36. 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(), ); } }
  37. 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(), ); } }
  38. 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(), ); } }
  39. 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(), ); } }
  40. 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(), ); } }
  41. 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(), ); } }
  42. 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(), ); } }
  43. 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(...), . . ]; }
  44. 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(...); } }
  45. 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(...); } }
  46. 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(...); } }
  47. 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(...); } }
  48. 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()) ); } }
  49. 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()) ); } }
  50. 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()) ); } }
  51. 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() ], ), ) ] ); } }
  52. 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() ], ), ) ] ); } }
  53. 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() ], ), ) ] ); } }
  54. 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() ], ), ) ] ); } }
  55. 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() ], ), ) ] ); } }
  56. 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() ], ), ) ] ); } }
  57. @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() ], ), ) ] ); }
  58. @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() ], ), ) ] ); }
  59. @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() ], ), ) ] ); }
  60. 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() ], ), ) ] ); }
  61. 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)) ], ), )
  62. 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(...) ], ), )
  63. 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(...) ], ), )
  64. 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(...) ], ), )
  65. 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(...) ], ), )
  66. 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(...) ], ), )
  67. 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(...) ], ), )
  68. What Else ? Unit, Integration & Widget Testing ! Animations

    Accessing Platform Specific Features Great Tooling (Dart Analyzer, Render Tree Dumps, Perf Overlays)