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

Best Practices and Tips
 in Flutter App Develop...

Best Practices and Tips
 in Flutter App Development

This is my presentation file on DevFestPisa 2019.

#DevFest
#DevFestPisa
#Flutter
#mobile

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