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

Best Practices and Tips
 in Flutter App Develop...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Best Practices and Tips
 in Flutter App Development

This is my presentation file on DevFestPisa 2019.

#DevFest
#DevFestPisa
#Flutter
#mobile

Avatar for Kenichi Kambara

Kenichi Kambara

April 13, 2019
Tweet

More Decks by Kenichi Kambara

Other Decks in Technology

Transcript

  1. About me • Mobile App Development • Technical Speeches •

    Droidcon UK/FR/NL/ES/SH • Devoxx UA • Developers Summit • Android Bazaar and Conference • StackOverflow DevDays • Cloud Days • Google I/O Extended Tokyo 2018 •Technical Writings •[Official] NTT TechnoCross •[Private] iplatform.org Kenichi Kambara (@korodroid)
  2.   Cross-Platform Activity (StackOverflow) Number of StackOverflow question views

    tagged with each of four popular UI frameworks over time (https://bit.ly/2A0tzuK)
  3.   Cross-Platform Activity (StackOverflow) Number of StackOverflow question views

    tagged with each of four popular UI frameworks over time (https://bit.ly/2A0tzuK)
  4. 1. Has known a bit about “Flutter”? 2. Has developed

    “Hello Flutter”? 3. Has developed any Flutter apps? 4. Has published any Flutter apps? ? Questions
  5. Very similar to Java/Java Script import 'package:flutter/material.dart'; void main() {

    runApp( Center( child: Text( ‘Hello, Flutter', textDirection: TextDirection.ltr, ), ), ); }   3. Dart
  6. Very similar to Java/Java Script import 'package:flutter/material.dart'; void main() {

    runApp( Center( child: Text( ‘Hello, Flutter', textDirection: TextDirection.ltr, ), ), ); }   3. Dart
  7. Very similar to Java/Java Script import 'package:flutter/material.dart'; void main() {

    runApp( Center( child: Text( ‘Hello, Flutter', textDirection: TextDirection.ltr, ), ), ); }   3. Dart
  8. Very similar to Java/Java Script import 'package:flutter/material.dart'; void main() {

    runApp( Center( child: Text( ‘Hello, Flutter', textDirection: TextDirection.ltr, ), ), ); }   3. Dart
  9. Very similar to Java/Java Script import 'package:flutter/material.dart'; void main() {

    runApp( Center( child: Text( ‘Hello, Flutter', textDirection: TextDirection.ltr, ), ), ); }   3. Dart Note: Optional “new”, “const” from Dart 2.x
  10. Simple Flutter Material App import 'package:flutter/material.dart'; void main() => runApp(MyApp());

    class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: Text(‘My First Flutter'), ), body: Center( child: Text(‘Hello, Flutter'), ), ), ); } } change to the below code (<project>/libs/main.dart)  
  11. Simple Flutter Material App import 'package:flutter/material.dart'; void main() => runApp(MyApp());

    class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: Text(‘My First Flutter'), ), body: Center( child: Text(‘Hello, Flutter'), ), ), ); } }   Writing Dart code for Layout ( LayoutXML, StoryBoard)
  12. Simple Flutter Material App import 'package:flutter/material.dart'; void main() => runApp(MyApp());

    class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: Text(‘My First Flutter'), ), body: Center( child: Text(‘Hello, Flutter'), ), ), ); } } change to the below code (<project>/libs/main.dart)  
  13. StatefulWidget (Dynamic Screen Update) class MyApp extends StatelessWidget { @override

    Widget build(BuildContext context) { return MaterialApp( home: MyHomePage(title: 'Welcome to Flutter'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() =>_MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } … Note: State (Manage Widget Status)  
  14. Text Column Dropdown Button Text Field Raised Button Dropdown Button

    Text Field Scaffold AppBar Body
 (Container) Top-Down Approach  
  15. child: Container( child: Column( mainAxisSize: MainAxisSize.max, children: <Widget>[ Expanded( child:

    Container( child: Row( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[button1], ), ), flex: 1, ), Expanded( child: Container( child: Row( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[button2], ), ), flex: 2, ), ], ), ), Expanded Widget+flex property Relative proportions  
  16. Implementing with Dart   •Implicit Widget •No need AnimationController

    (using setState()) •Customization: Moderate
 •Transition Widget •Requires AnimationController •Customization: Middle •Explicit Widget •Requires AnimationController •Customization: High Implicit Widget Transition Widget
  17. Code Sample (Implicit Widget)   body: Center( child: AnimatedOpacity(

    opacity: _visible ? 1.0 : 0.0, duration: Duration(milliseconds: 2000), child: Image.asset('images/chara.png')), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _visible = !_visible; }); }, tooltip: ‘Switch Opacity', child: Icon(Icons.flip), ),
  18. Code Sample (Transition Widget)   body: Center( child: Column(

    mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ScaleTransition( scale: CurvedAnimation( parent: _controller, curve: Curves.easeIn, ), child: Image.asset('images/chara.png'), ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: switchExpansion, tooltip: 'Switch', child: Icon(Icons.add), ),
  19. Code Sample (Transition Widget)   class _MyHomePageState extends State<MyHomePage>

    with SingleTickerProviderStateMixin { AnimationController _controller; @override void initState() { super.initState(); _controller = new AnimationController( vsync: this, duration: const Duration(milliseconds: 500), )..forward(); } void switchExpansion() { if (_controller.isDismissed) { _controller.forward(); } else { _controller.reverse(); } } // … }
  20. Flare   Adding Flare package to Flutter Project dependencies:

    flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 ## Flare flare_flutter: pubspec.yaml
  21. Flare   Importing Flare data (*.flr) and Coding return

    Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: FlareActor( "assets/sample.flr", animation: "sample01", fit: BoxFit.contain, )), ); } main.dart
  22.   BLoC Sample (Input/Sink) floatingActionButton: FloatingActionButton( onPressed: () =>

    _controller.sink.add(++_counter), tooltip: 'Increment', child: Icon(Icons.add), ),
  23.   BLoC Sample (Output/Stream) StreamBuilder( stream: _controller.stream, initialData: 0,

    builder: (BuildContext context, AsyncSnapshot snapshot) { return new Text( '${snapshot.data}', style: Theme.of(context).textTheme.display1, ); }, )
  24. Sample Code using Packages import 'package:shared_preferences/shared_preferences.dart'; _saveSampleData(String value) async {


    SharedPreferences prefs = await SharedPreferences.getInstance();
 await prefs.setString('key1', value);
 } (3)  
  25. Recommended Packages •http •HTTP Client •Easy to implement REST
 •firebase

    •lol Firebase!!! •Easy to add Firebase features •share •Contents share (Similar to Android/iOS) •e.g. Share to SNS  
  26. Problem: Boilerplate   class MainPage extends StatefulWidget { @override

    _MainPageState createState() => _MainPageState(); } class _MainPageState extends State<MainPage> { @override Widget build(BuildContext context) { return Container(); } } class SubPage extends StatelessWidget { @override Widget build(BuildContext context) { return Container(); } }
  27. Step0. Auto-Generated File 2 files are gerenated automatically. Note: If

    these files aren’t gererated, close and open again.  
  28. Step2. Preparing Language Resources res/values/
 strings_en.arb <- Copy and Create

    other files (e.g. strings_it.arb) { "appTitle": “Sample App", "appSummary": "Hello" } strings_en.arb strings_it.arb { "appTitle": "App di esempio", "appSummary": “Ciao” } Note: To modify language resources, it’s requreid to modify strings_*.arb.  
  29. Flutter 1.2 Overview •Dart 2.2 •Material & Cupertino Widget Sets

    •In-App Purchases •Android App Bundles •New Developer Tools  
  30. Flutter 1.2 Overview •Dart 2.2 •Material & Cupertino Widget Sets

    •In-App Purchases •Android App Bundles •New Developer Tools  
  31. Dart DevTools (Web Tools) 1. Widget Inspector 2. Timeline View

    3. Source-level Debugger 4. Logging View  
  32. Please let me know if you have any requests 


    such as technical speeches, technical writings and so on. Facebook:http://fb.com/kanbara.kenichi Twitter:@korodroid LinkedIn:http://www.linkedin.com/in/korodroid Thank you so much