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

Droidcon SF 2017: Building Modern Cross Platform Apps with Flutter

E8da8d13d06ca69dbe019ecad71ed2a4?s=47 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.

E8da8d13d06ca69dbe019ecad71ed2a4?s=128

vinaygaba

November 06, 2017
Tweet

More Decks by vinaygaba

Other Decks in Technology

Transcript

  1. lutter Building Modern X - Platform Apps with Vinay Gaba

    @vinaygaba
  2. What is Flutter ?

  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. 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
  8. None
  9. 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
  10. 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 ?
  11. None
  12. None
  13. None
  14. But how is it different ?

  15. 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
  16. 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 ?
  17. Source: https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514

  18. Source: https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514

  19. Source: https://hackernoon.com/whats-revolutionary-about-flutter-946915b09514

  20. 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 ?
  21. 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
  22. 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
  23. 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
  24. Flutter Widget Framework

  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. None
  31. Hello World

  32. $ git clone -b alpha https://github.com/flutter/flutter.git $ export PATH=`pwd`/flutter/bin:$PATH

  33. $ flutter doctor

  34. $ flutter doctor

  35. $ flutter create myapp

  36. $ flutter create myapp

  37. None
  38. None
  39. 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, ); } }
  40. 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, ); } }
  41. 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, ); } }
  42. 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, ); } }
  43. 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, ); } }
  44. 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, ); } }
  45. 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, ); } }
  46. 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, ); } }
  47. 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, ); } }
  48. 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, ); } }
  49. Lets Prototype!

  50. None
  51. 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(); } }
  52. 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(); } }
  53. 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(); } }
  54. 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(); } }
  55. 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(); } }
  56. 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(); } }
  57. 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(); } }
  58. class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {

    return new Container(); } }
  59. class GmailInbox extends StatelessWidget { @override Widget build(BuildContext context) {

    return new Container(); } }
  60. 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(), ); } }
  61. 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(), ); } }
  62. 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(), ); } }
  63. 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(), ); } }
  64. 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(), ); } }
  65. 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(), ); } }
  66. 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(), ); } }
  67. 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: "XYZ@gmail.com", subject: "Email Subject", emailBody: "Thanks for nothing!", timeStamp: "Oct 13"), new Email(...), . . ]; }
  68. 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(...); } }
  69. 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(...); } }
  70. 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(...); } }
  71. 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(...); } }
  72. class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override

    Widget build(BuildContext context) { return new Scaffold(...); } }
  73. class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override

    Widget build(BuildContext context) { return new Scaffold(...); } }
  74. class GmailInbox extends StatelessWidget { GmailInbox({this.emails}); final List<Email> emails; @override

    Widget build(BuildContext context) { return new Scaffold(...); } }
  75. 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()) ); } }
  76. 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()) ); } }
  77. 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()) ); } }
  78. None
  79. None
  80. Row Widget Column Row Widget Widget Widget Widget

  81. 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() ], ), ) ] ); } }
  82. 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() ], ), ) ] ); } }
  83. 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() ], ), ) ] ); } }
  84. 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() ], ), ) ] ); } }
  85. 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() ], ), ) ] ); } }
  86. 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() ], ), ) ] ); } }
  87. @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() ], ), ) ] ); }
  88. @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() ], ), ) ] ); }
  89. @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() ], ), ) ] ); }
  90. 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() ], ), ) ] ); }
  91. new Container( child: new Column( children: <Widget>[ new Row(), new

    Text(), new Text() ], ), )
  92. new Container( child: new Column( children: <Widget>[ new Row(), new

    Text(), new Text() ], ), )
  93. 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)) ], ), )
  94. 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(...) ], ), )
  95. 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(...) ], ), )
  96. 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(...) ], ), )
  97. 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(...) ], ), )
  98. 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(...) ], ), )
  99. 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(...) ], ), )
  100. iPhone Android

  101. What Else ?

  102. What Else ? Unit, Integration & Widget Testing ! Animations

    Accessing Platform Specific Features Great Tooling (Dart Analyzer, Render Tree Dumps, Perf Overlays)
  103. Thank you! Vinay Gaba @vinaygaba