Slide 1

Slide 1 text

FlutterͰ
 QRίʔυϦʔμʔ
 Λࡶʹ࡞ͬͯΈͨ Flutter Meetup Tokyo #2

Slide 2

Slide 2 text

About Me • Dart͕࠷ڧͱݴ͍ଓ͚ͨਓͰ͢ʂ • ϓϩήʔϚʔ໨ࢦͯ͠·͢ʂ • Discord : operandoOS • Steam : operandoOS • YouTubeͰήʔϜ഑৴ͯ͠·͢ʂ • https://www.youtube.com/user/opp228

Slide 3

Slide 3 text

Demo

Slide 4

Slide 4 text

ΞϓϦͷίʔυ • Flutter QRCode Scanner APP • https://github.com/operando/ FlutterQRScanner-App

Slide 5

Slide 5 text

࡞ۀ࣌ؒ 4࣌ؒ͘Β͍

Slide 6

Slide 6 text

࡞ΔաఔΛͬ͘͟Γ঺հ

Slide 7

Slide 7 text

ͳͥQRίʔυϦʔμʔΞϓϦΛ࡞Δͷ͔ • Androidͷඪ४ΧϝϥΞϓϦ͸QRίʔυಡΈࠐΈͰ͖ͳ͍ • iOS͸Ͱ͖Δ • ੈʹ͋ΔQRίʔυϦʔμʔΞϓϦ޿ࠂ͕ग़ͯݏʔ • ࣗ෼Ͱ࡞Ε͹͍͍ͷͰ͸ʁ • FlutterͰ΍Δ͔ʔ

Slide 8

Slide 8 text

QRίʔυϦʔμʔͷLibraryΛ୳͢ • QR Code Scanner AppΛ࡞ͬͯΔYouTubeΛݟ͚ͭͨ • Flutter: QR Code Scanner App | Barcode Scan • https://www.youtube.com/watch?v=siuJhQ9BqsU • Flutter QRCode Scanner APP • https://github.com/iampawan/FlutterQRScanner-App

Slide 9

Slide 9 text

QRίʔυϦʔμʔͷLibraryΛ୳͢ • ͜ͷํͷYouTubeνϟϯωϧFlutterಈըͷ
 ݁ߏ͋ͬͯྑͦ͞͏ • MTechViral • https://www.youtube.com/channel/ UCFTM1FGjZSkoSPDZgtbp7hA

Slide 10

Slide 10 text

QR Code Scanner AppΛಈ͔ͯ͠ΈΔ • git cloneͯ͠ɺIntelliJ IDEAͰ։͘ • AndroidΞϓϦͰϏϧυ͢Δ

Slide 11

Slide 11 text

ಈ͍ͨ

Slide 12

Slide 12 text

QR Code Scanner AppͷίʔυΛ
 ݟͯΈΔ • QRίʔυಡΈࠐΈʹ͸LibraryΛ࢖ͬͯΔ • barcode_scan • https://github.com/apptreesoftware/ flutter_barcode_reader

Slide 13

Slide 13 text

QR Code Scanner AppͷίʔυΛ
 ݟͯΈΔ • barcode_scan͸QRίʔυಡΈࠐΈʹ
 zxingΛ࢖ͬͯΔ • https://github.com/zxing/zxing • GoogleͷMobile Visionʹࠩ͠ସ͍͑ͨཉ͕
 ग़͖ͯͨ

Slide 14

Slide 14 text

Flutter Mobile Vision Package Λ୳ͯ͠ΈΔ • ͋ͬͨʔʂ • flutter_mobile_vision • https://github.com/edufolly/ flutter_mobile_vision • iOS͸ະରԠͬΆ͍

Slide 15

Slide 15 text

flutter_mobile_visionʹࠩ͠ସ͑Δ • ؆୯ʹࠩ͠ସ͑ΒΕͨ

Slide 16

Slide 16 text

Future _scanQR() async { List barcodes = []; try { barcodes = await FlutterMobileVision.scan( flash: false, autoFocus: true, formats: Barcode.ALL_FORMATS, multiple: false, showText: true, camera: FlutterMobileVision.CAMERA_BACK, fps: 30.0, ); setState(() { result = barcodes[0].displayValue; }); } on Exception { barcodes.add(new Barcode('Failed to get barcode.')); } } @override Widget build(BuildContext context) { ... body: Center( ... floatingActionButton: FloatingActionButton.extended( icon: Icon(Icons.camera_alt), label: Text("Scan"), onPressed: _scanQR, ), floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, ); }

Slide 17

Slide 17 text

ͳΜͩɺͰ͖ͪ·ͬͨͥ...

Slide 18

Slide 18 text

ػೳ௥Ճͯ͠ΈΑ͏ • ಡΈࠐΜͩQRίʔυͷจࣈྻΛγΣΞ͢Δ • ಡΈࠐΈཤྺΛ࡞Δ • ࠓճ͸ͬͪ͜ͷ࿩Λ͠·͢

Slide 19

Slide 19 text

ಡΈࠐΈཤྺΛ࡞Δ • ಡΈࠐΈཤྺը໘Λ࡞Δ • ಡΈࠐΈཤྺը໘΁ͷભҠΛ࡞Δ • ಡΈࠐΜͩ৘ใΛDBʹอଘ͢Δ • ಡΈࠐΈཤྺҰཡΛදࣔ͢Δ

Slide 20

Slide 20 text

ಡΈࠐΈཤྺը໘Λ࡞Δ • HistoryStateͷத਎͸ޙ΄Ͳ class History extends StatefulWidget { @override HistoryState createState() { return HistoryState(); } }

Slide 21

Slide 21 text

ಡΈࠐΈཤྺը໘΁ͷભҠΛ࡞Δ void main() => runApp(MaterialApp( debugShowCheckedModeBanner: false, home: HomePage(), routes: { 'history': (_) => History()}, ));

Slide 22

Slide 22 text

ಡΈࠐΈཤྺը໘ʹListViewΛදࣔ͢Δ • ListViewͷ࢖͍ํΛެࣜυΩϡϝϯτ͔ΒֶͿ • ͱΓ͋͑ͣݻఆσʔλΛදࣔͯ͠ΈΔ

Slide 23

Slide 23 text

class HistoryState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Scanner History"), ), body: new ListView.builder( itemCount: 1, itemBuilder: (context, index) { return ListTile(title: Text("χʔτ")); })); } }

Slide 24

Slide 24 text

ಡΈࠐΜͩ৘ใΛDBʹอଘ͢Δ • DB Library୳ͯ͠ΈΔ • sqflite • https://github.com/tekartik/sqflite

Slide 25

Slide 25 text

sqfliteͷ࢖͍ํΛֶͿ • READMEಡΜͩΓɺexampleಡΜͩΓ͢Δ • ͋ͱ͸งғؾͰίϐϖ͖ͯͨ͠ɺॻ͖׵͑Δ • example͕ͪΐͬͱΘ͔Γʹ͔ͬͨ͘ͷͰ
 ؤுΔ...

Slide 26

Slide 26 text

DBʹอଘ͞Εͨ৘ใݟ͍ͨ... • AndroidͳΒStetho࢖͑͹ʂʂ • flutter_stetho • https://github.com/brianegan/flutter_stetho • Ͱ΋DBݟΕͳ͔ͬͨ... • sqfliteͰDBΛ࡞ͬͯΔσΟϨΫτϦ͕͋Ε͔΋

Slide 27

Slide 27 text

อଘͨ͠ಡΈࠐΈཤྺΛ ListViewʹදࣔ͢Δ • DB͔ΒཤྺΛಡΈࠐΜͰɺऔಘͰ͖ͨΒ setState͢Δ͚ͩ

Slide 28

Slide 28 text

class HistoryState extends State { List _items = []; @override void initState() { super.initState(); _initDatabase(); } _initDatabase() async { String path = await getDatabaseFilePath("scan_history.db"); Database db = await openReadOnlyDatabase(path); List data = await db.query("scan_hisoty", columns: ["text"]); List items = []; data.forEach((e) => items.add(ScanItem.fromMap(e))); setState(() { _items = items; }); await db.close(); } @override Widget build(BuildContext context) { return Scaffold( ... body: new ListView.builder( itemCount: _items.length, itemBuilder: (context, index) { return ListTile(title: Text("${_items[index].text}")); })); } }

Slide 29

Slide 29 text

ΞϓϦͷ࠷ऴతͳDependencies dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.2 flutter_mobile_vision: ^0.1.0 share: "^0.5.0" sqflite: "^0.8.9" path_provider: "^0.4.0" dev_dependencies: flutter_stetho: 0.1.1 flutter_test: sdk: flutter

Slide 30

Slide 30 text

࡞ͬͯΈͯײͨ͜͡ͱ • ͱΓ͋͑ͣLibrary୳͕ͪ͠ • ࣗ෼͕࣮૷͠ͳͯ͘΋͖ͬͱ͋Δײ • ࣮ࡍʹେମ͸͋Δ

Slide 31

Slide 31 text

࡞ͬͯΈͯײͨ͜͡ͱ • ยํͷϓϥοτϑΥʔϜ͚࣮ͩ૷ͯ͠΋
 શવྑͦ͞͏ • ࡞Γ͍ͨ΋ͷΛ͙͢࡞ΕΔ • Α͘஌Βͳ͍͔Βࡉ͔͍͜ͱʹ
 ͩ͜ΘΒͳ͘ͳΔ

Slide 32

Slide 32 text

࡞ͬͯΈͯײͨ͜͡ͱ • async / awaitࡶʹ࢖͍͕ͪ • ཧղͯ͜͠͏ͳʂ • TextΛදࣔ͢Δํ๏๨Ε͕ͪ • ίϯϙʔωϯτʹจࣈྻࢦఆ͢ΔϓϩύςΟ͕͋Δͱ צҧ͍͢Δ • WidgetͩΑʂʂ

Slide 33

Slide 33 text

࡞ͬͯΈͯײͨ͜͡ͱ • ࠷ѱ main.dartʹશ෦ॻ͍ͯ΋ྑͦ͞͏ • ͋ͱͰ෼͚Ε͹͍͍͠ • ίϐϖ͗͢͠ΔͱϋϚΓ͕ͪ • ίϐϖͨ͠ίʔυ͕༧ظͤ͵ಈ͖Λͯ͠Δͷ͋ΔΑͶ • ϓϩάϥϛϯάͷջ͔͠͞Λײͨ͡

Slide 34

Slide 34 text

࡞ͬͯΈͯײͨ͜͡ͱ • SDKͷ࢖͍ํΘ͔Βͳ͔ͬͨΒ
 υΩϡϝϯτಡΉ͔தͷίʔυಡΉํ͕ૣͦ͏ • ORM Library͕΄͍͠ͱ͜Ζ... • DartͰ࣮૷Ͱ͖Δ͔ͳʁ

Slide 35

Slide 35 text

࡞ͬͯΈͯײͨ͜͡ͱ • droidkaigi2018-flutterݟͯΈΔͱྑͦ͞͏ • https://github.com/konifar/ droidkaigi2018-flutter

Slide 36

Slide 36 text

Thanks!