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

Flutter - how to make a beautiful app in an hour?

Flutter - how to make a beautiful app in an hour?

Announced at Google I/O ’17 Flutter is a new open source library for creating cross-platform mobile applications with beautiful UI. Is it something new? Is it needed? Will this be a future? In this presentation I'd like to give an overview of approach in creating mobile applications in Flutter, point advantages of this solution and present example of application. After this talk you'll be able to face a question - is Flutter something for you?

Paulina Szklarska

June 14, 2018
Tweet

More Decks by Paulina Szklarska

Other Decks in Technology

Transcript

  1. Paulina Szklarska Android Developer @ DroidsOnRoids Toast Wrocław meetups co-org

    GDG Wrocław co-org Women Techmakers Wrocław lead cat owner travel enthusiast @pszklarska @pszklarska @p_szklarska
  2. 1. What is Flutter? 2. How is Flutter different from

    other solutions? 3. How to make an app? 4. Cool, but… What about X/Y/Z? Agenda
  3. Flutter is Google’s mobile UI framework for crafting high-quality native

    interfaces on iOS and Android in record time. What is Flutter?
  4. Android Equivalents Android Flutter LinearLayout Column RelativeLayout Column, Row, Stack

    RecyclerView ListView gestures GestureDetector padding Padding Composition > Inheritance
  5. How to make an app? 3. Setup your Android/iOS device/emulator

    $ flutter doctor [-] Android toolchain - develop for Android devices • Android SDK at /Users/obiwan/Library/Android/sdk ✗ Android SDK is missing command line tools; download from https://goo.gl/XxQghQ • Try re-installing or updating your Android SDK, visit https://flutter.io/setup/#android-setup for detailed instructions. 1. Get the Flutter SDK: https://flutter.io/setup-macos/ 2. Run flutter doctor:
  6. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( ),o ); }a }a How to make an app?
  7. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Column( )),o ); }a }a How to make an app?
  8. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Column( children: <Widget>[ new Flexible( ),b ], )), ); }a }a How to make an app?
  9. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder( ),c ),b ], )),a );a }a }a How to make an app?
  10. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder( itemCount: 10, ),c ),b ], )), ); }a }a How to make an app?
  11. body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder(

    itemCount: 10, itemBuilder: (_, position) => new ListTile( ), ),c ),b ], )), How to make an app?
  12. body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder(

    itemCount: 10, itemBuilder: (_, position) => new ListTile( leading: new Icon(Icons.done), ), ),c ),b ], )), How to make an app?
  13. body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder(

    itemCount: 10, itemBuilder: (_, position) => new ListTile( leading: new Icon(Icons.done), ), ),c ),b ], )), How to make an app?
  14. body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder(

    itemCount: 10, itemBuilder: (_, position) => new ListTile( leading: new Icon(Icons.done), title: new Text("Tile No. $position"), ), ),c ),b ], )), How to make an app?
  15. body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder(

    itemCount: 10, itemBuilder: (_, position) => new ListTile( leading: new Icon(Icons.done), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), ), ),c ),b ], )), How to make an app?
  16. body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder(

    itemCount: 10, itemBuilder: (_, position) => new ListTile( leading: new CircleAvatar( child: new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), ),9 ),c ),b ], )), How to make an app?
  17. itemBuilder: (_, position) => new ListTile( leading: new CircleAvatar( child:

    new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), ),9 How to make an app?
  18. itemBuilder: (_, position) => new ListTile( leading: new CircleAvatar( child:

    new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text(“Subtitle"), trailing: new Checkbox( value: true, onChanged: _handleCheck)), ), How to make an app?
  19. itemBuilder: (_, position) => new Card( child: new ListTile( leading:

    new CircleAvatar( child: new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), trailing: new Checkbox( value: true, onChanged: _handleCheck)), ), How to make an app?
  20. itemBuilder: (_, position) => new Padding( padding: const EdgeInsets.all(4.0), child:

    new Card( child: new ListTile( leading: new CircleAvatar( child: new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), trailing: new Checkbox( value: true, onChanged: _handleCheck)), ),8 ),7 How to make an app?
  21. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter’, home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ),a body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder( itemCount: 10, itemBuilder: (_, position) => new Padding( padding: const EdgeInsets.all(4.0), child: new Card( child: new ListTile( leading: new CircleAvatar( child: new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), trailing: new Checkbox( value: true, onChanged: _handleCheck)), ),8 ),7 ),c ),b ], )), ); }a }a How to make an app?
  22. home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to

    Flutter'), ),a body: new Column( . . . );a }a How to make an app?
  23. home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to

    Flutter’), theme: new ThemeData( primarySwatch: Colors.blue, accentColor: Colors.pinkAccent ), ),a body: new Column( . . . );a }a How to make an app?
  24. home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to

    Flutter’), theme: new ThemeData( primarySwatch: Colors.purple, accentColor: Colors.pinkAccent ), ),a body: new Column( . . . );a }a How to make an app?
  25. home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to

    Flutter’), theme: new ThemeData( primarySwatch: Colors.purple, accentColor: Colors.pinkAccent ), ),a body: new Column( . . . );a }a How to make an app?
  26. import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends

    StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter’, theme: new ThemeData( primarySwatch: Colors.purple, accentColor: Colors.pinkAccent ), home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder( itemCount: 10, itemBuilder: (_, position) => new Padding( padding: const EdgeInsets.all(4.0), child: new Card( child: new ListTile( leading: new CircleAvatar( child: new Icon(Icons.done)), title: new Text("Tile No. $position"), subtitle: new Text("Subtitle"), trailing: new Checkbox( value: true, onChanged: _handleCheck)), ), ), ),c ),b ], )), ); }a }a How to make an app?
  27. Stateless vs. Stateful Widget immutable (only layout, no state) no

    changes (new change -> new object) eg. simple Text
  28. class MutableWidget extends StatefulWidget { @override MutableWidgetState createState() => new

    MutableWidgetState(); } class MutableWidgetState extends State<MutableWidget> { String text = "Hello!"; @override Widget build(BuildContext context) { return new Text(text); } void changeText() { setState(() { text = "Flutter!"; }); } }
  29. Accessing external services Flutter app (client) iOS (host) Android (host)

    FlutterMethodChannel MethodChannel MethodChannel
  30. Accessing external services import android.os.Bundle import io.flutter.app.FlutterActivity import io.flutter.plugin.common.MethodChannel import

    io.flutter.plugins.GeneratedPluginRegistrant class MainActivity() : FlutterActivity() { private val CHANNEL = "samples.flutter.io/battery" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) GeneratedPluginRegistrant.registerWith(this) MethodChannel(flutterView, CHANNEL) .setMethodCallHandler { call, result -> // TODO } } }
  31. Accessing external services import android.os.Bundle import io.flutter.app.FlutterActivity import io.flutter.plugin.common.MethodChannel import

    io.flutter.plugins.GeneratedPluginRegistrant class MainActivity() : FlutterActivity() { private val CHANNEL = "samples.flutter.io/battery" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) GeneratedPluginRegistrant.registerWith(this) MethodChannel(flutterView, CHANNEL) .setMethodCallHandler { call, result -> // TODO } } }
  32. Accessing external services if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel();

    if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error(“UNAVAILABLE", "Battery level not available.”, null); } } else { result.notImplemented(); }
  33. Accessing external services if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel();

    if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error(“UNAVAILABLE", "Battery level not available.”, null); } } else { result.notImplemented(); }
  34. Accessing external services if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel();

    if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error(“UNAVAILABLE", "Battery level not available.”, null); } } else { result.notImplemented(); }
  35. Accessing external services if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel();

    if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error(“UNAVAILABLE", "Battery level not available.”, null); } } else { result.notImplemented(); }
  36. Accessing external services static const platform = const MethodChannel('samples.flutter.io/battery'); final

    int result = await platform.invokeMethod('getBatteryLevel'); batteryLevel = 'Battery level at $result % .’;
  37. Navigation void main() { runApp(new MaterialApp( home: new MyAppHome(), //

    becomes the route named '/' routes: <String, WidgetBuilder> { '/a': (BuildContext context) => new MyPage(title: 'page A'), '/b': (BuildContext context) => new MyPage(title: 'page B'), '/c': (BuildContext context) => new MyPage(title: 'page C'), }, )); } Navigator.of(context).pushNamed('/b');
  38. Activity lifecycle events class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {

    AppLifecycleState _lastLifecyleState; @override void didChangeAppLifecycleState(AppLifecycleState state) { setState(() { _lastLifecyleState = state; }); } }
  39. Activity lifecycle events Flutter Android iOS Description inactive — ✓

    not receiving user input paused onPause() ✓ not visible to user resumed onPost Resume() ✓ visible and responding suspending onStop() — will be suspended
  40. Facts 1. Flutter is cool. 2. Flutter is very fast

    (development, application). 3. Flutter is super fun. 4. Flutter is easy to start. 5. Flutter is beautiful.
  41. Useful Resources GitHub Samples: https://github.com/pszklarska/HelloFlutter Flutter: https://flutter.io/ Technical Overview: https://flutter.io/technical-overview/

    Keep it Simple, State (DartConf 2018) https://www.youtube.com/watch?v=zKXz3pUkw9A Flutter - 5 reasons why you may love it https://hackernoon.com/flutter-5-reasons-why-you-may-love- it-55021fdbf1aa