Slide 1

Slide 1 text

'MVUUFS޲͚ͷύοέʔδ ࡞ͬͯQVCͰެ։ͨ͠࿩ !LVSPOFLPNJDIBFM Ͷ͜·͍͚Δ

Slide 2

Slide 2 text

˓˓˓ͳϩδοΫ͕ඞཁͩɾɾɾ ˚˚˚ͳը໘෦඼͕͋ͬͨΒ͍͍ͷʹɾɾɾ Ͱ΋ɺଞʹ΋ඞཁͱ͍ͯ͠Δਓ͕͍ͦ͏ͩͳʁʁʁ

Slide 3

Slide 3 text

'MVUUFS %BSU ΤίγεςϜ l1VCz IUUQTQVCEBSUMBOHPSH

Slide 4

Slide 4 text

1VC cc %BSUݴޠ༻ͷύοέʔδϚωʔδϟʔ 3VCZͰ͍͏ͱ͜ΖͷHFN /PEFKTͰ͍͏ͱ͜ΖͷOQN

Slide 5

Slide 5 text

७ਮͳ%BSUݴޠ༻ͷϥΠϒϥϦ΋ ͋Ε͹ɺ'MVUUFS༻ͷը໘෦඼ 8JEHFU ΋͋Γ·͢

Slide 6

Slide 6 text

ΦϨΦϨ8JEHFUΛ શੈքʹެ։͢Δʢஏʣ

Slide 7

Slide 7 text

ಈػ

Slide 8

Slide 8 text

'MVUUFSඪ४෇ଐͷ8JEHFU l4USFBN#VJMEFSz ʮ4USFBNʯͱ͍͏ϥΠϒϥϦΛ࢖ͬͯɺ ඇಉظʹσʔλΛऔಘͯ͠ը໘Λ࡞Γ͍ͨ࣌ʹ࢖͑Δ8JEHFUɻ ·ͩσʔλ͕औಘͰ͖ͯͳ͍ͱ͖͸ʙ σʔλऔಘ͕Τϥʔͷͱ͖͸ʙ σʔλ͕औಘͰ͖ͨΒʙ Έ͍ͨͳ෼ذΛ΋ͬͯը໘Λ࡞Δ͜ͱ͕Ͱ͖Δɻ 4USFBNͷঢ়ଶ͕มΘͬͨΒࣗಈͰ࠶ඳը΋ͯ͘͠ΕΔɻ

Slide 9

Slide 9 text

'MVUUFSඪ४෇ଐͷ8JEHFU l4USFBN#VJMEFSz ʮ4USFBNʯͱ͍͏ϥΠϒϥϦΛ࢖ͬͯɺ ඇಉظʹσʔλΛऔಘͯ͠ը໘Λ࡞Γ͍ͨ࣌ʹ࢖͑Δ8JEHFUɻ ·ͩσʔλ͕औಘͰ͖ͯͳ͍ͱ͖͸ʙ σʔλऔಘ͕Τϥʔͷͱ͖͸ʙ σʔλ͕औಘͰ͖ͨΒʙ Έ͍ͨͳ෼ذΛ΋ͬͯը໘Λ࡞Δ͜ͱ͕Ͱ͖Δɻ 4USFBNͷঢ়ଶ͕มΘͬͨΒࣗಈͰ࠶ඳը΋ͯ͘͠ΕΔɻ ίʔυ͕ϞϠοͱ͢Δʂ

Slide 10

Slide 10 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('ૉͷStreamBuilder'), ), body: StreamBuilder( stream: widget.stream, builder: (BuildContext context, AsyncSnapshot snapshot) { // ΋͠ΤϥʔͳΒΞΠίϯΛදࣔʢ௨৴Τϥʔ࣌ͳͲʣ if (snapshot.hasError) { return Icon(Icons.error_outline); } // σʔλ͕·ͩಧ͍͍ͯͳ͍ؒ͸ɺۭനΛදࣔʢॳճඳը࣌ͳͲʣ if (!snapshot.hasData) { return Container(); } // ʻຊ໋ʼσʔλ͕औΕͨΒը໘ʹදࣔ return Center( child: Text( snapshot.data, style: TextStyle(fontSize: 30.0), )); }, ), );

Slide 11

Slide 11 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('ૉͷStreamBuilder'), ), body: StreamBuilder( stream: widget.stream, builder: (BuildContext context, AsyncSnapshot snapshot) { // ΋͠ΤϥʔͳΒΞΠίϯΛදࣔʢ௨৴Τϥʔ࣌ͳͲʣ if (snapshot.hasError) { return Icon(Icons.error_outline); } // σʔλ͕·ͩಧ͍͍ͯͳ͍ؒ͸ɺۭനΛදࣔʢॳճඳը࣌ͳͲʣ if (!snapshot.hasData) { return Container(); } // ʻຊ໋ʼσʔλ͕औΕͨΒը໘ʹදࣔ return Center( child: Text( snapshot.data, style: TextStyle(fontSize: 30.0), )); }, ), ); ඳըʹඞཁͳσʔλ 4USJOH ͸ɺ TOBQTIPUEBUBͷதʹೖ͍ͬͯΔ TOBQTIPUIBT&SSPSΛΈͯɺ Τϥʔ͕ൃੜͨ͠ͱ͖͸ԿΛඳը͢Δ͔෼ذ͢Δ TOBQTIPUIBT%BUBΛΈͯɺ σʔλ͕·ۭͩͷͱ͖͸ԿΛඳը͢Δ͔෼ذ͢Δ ˡ࣮͸͕͜͜ϝΠϯͰ࣮૷͠ͳ͚Ε͹͍͚ͳ͍෦෼ ˞ࡾ߲ԋࢉࢠͰॻ͍ͯΔέʔε΋Α͘Έ·͢ʢݸਓతʹ͸ಡΈͮΒ͍ʣ

Slide 12

Slide 12 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('ૉͷStreamBuilder'), ), body: StreamBuilder( stream: widget.stream, builder: (BuildContext context, AsyncSnapshot snapshot) { // ΋͠ΤϥʔͳΒΞΠίϯΛදࣔʢ௨৴Τϥʔ࣌ͳͲʣ if (snapshot.hasError) { return Icon(Icons.error_outline); } // σʔλ͕·ͩಧ͍͍ͯͳ͍ؒ͸ɺۭനΛදࣔʢॳճඳը࣌ͳͲʣ if (!snapshot.hasData) { return Container(); } // ʻຊ໋ʼσʔλ͕औΕͨΒը໘ʹදࣔ return Center( child: Text( snapshot.data, style: TextStyle(fontSize: 30.0), )); }, ), ); *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  *G TOBQTIPUIBT%BUB  Զ͸൑ఆࣜʹόάΛ࡞ΓࠐΉʂ ઈରʹͩʂ

Slide 13

Slide 13 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('ૉͷStreamBuilder'), ), body: StreamBuilder( stream: widget.stream, builder: (BuildContext context, AsyncSnapshot snapshot) { // ΋͠ΤϥʔͳΒΞΠίϯΛදࣔʢ௨৴Τϥʔ࣌ͳͲʣ if (snapshot.hasError) { return Icon(Icons.error_outline); } // σʔλ͕·ͩಧ͍͍ͯͳ͍ؒ͸ɺۭനΛදࣔʢॳճඳը࣌ͳͲʣ if (!snapshot.hasData) { return Container(); } // ʻຊ໋ʼσʔλ͕औΕͨΒը໘ʹදࣔ return Center( child: Text( snapshot.data, style: TextStyle(fontSize: 30.0), )); }, ), ); Զ͸൑ఆࣜʹόάΛ࡞ΓࠐΉʂ ઈରʹͩʂ

Slide 14

Slide 14 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('ૉͷStreamBuilder'), ), body: StreamBuilder( stream: widget.stream, builder: (BuildContext context, AsyncSnapshot snapshot) { // ΋͠ΤϥʔͳΒΞΠίϯΛදࣔʢ௨৴Τϥʔ࣌ͳͲʣ if (snapshot.hasError) { return Icon(Icons.error_outline); } // σʔλ͕·ͩಧ͍͍ͯͳ͍ؒ͸ɺۭനΛදࣔʢॳճඳը࣌ͳͲʣ if (!snapshot.hasData) { return Container(); } // ʻຊ໋ʼσʔλ͕औΕͨΒը໘ʹදࣔ return Center( child: Text( snapshot.data, style: TextStyle(fontSize: 30.0), )); }, ), ); Τϥʔ࣌ʹද͍ࣔͨ͠8JEHFU ۭന࣌ʹද͍ࣔͨ͠8JEHFU ਖ਼ৗ࣌ʹද͍ࣔͨ͠8JEHFU ͦΕͧΕࢦఆͨ͠Βྑ͘Ͷʁ

Slide 15

Slide 15 text

4BGFUZ4USFBN#VJMEFS lόάΔࢲͰ΋ͪΐͬͱ҆৺Ͱ͖Δ4USFBN#VJMEFSz

Slide 16

Slide 16 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('SafetyStreamBuilder'), ), body: SafetyStreamBuilder( stream: widget.stream, blankWidget: Container(), errorWidget: Icon(Icons.error_outline), builder: (BuildContext context, String message) => Center( child: Text( message, style: TextStyle(fontSize: 30.0), ), ), ), );

Slide 17

Slide 17 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('SafetyStreamBuilder'), ), body: SafetyStreamBuilder( stream: widget.stream, blankWidget: Container(), errorWidget: Icon(Icons.error_outline), builder: (BuildContext context, String message) => Center( child: Text( message, style: TextStyle(fontSize: 30.0), ), ), ), ); ˡσʔλ͕·ͩແ͍࣌ʹඳը͍ͨ͠8JEHFU ˡΤϥʔ࣌ʹඳը͍ͨ͠8JEHFU ˢσʔλऔಘ׬ྃޙʹඳը͍ͨ͠8JEHFU

Slide 18

Slide 18 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('SafetyStreamBuilder'), ), body: SafetyStreamBuilder( stream: widget.stream, blankWidget: Container(), errorWidget: Icon(Icons.error_outline), builder: (BuildContext context, String message) => Center( child: Text( message, style: TextStyle(fontSize: 30.0), ), ), ), ); JGจ͕ফ͑ͨʂ ਖ਼ৗܥʹूதͰ͖Δʂ όάΛ࡞Γͨͯ͘΋࡞Εͳ͍ʂ

Slide 19

Slide 19 text

@override Widget build(BuildContext context) => Scaffold( appBar: AppBar( title: Text('SafetyStreamBuilder'), ), body: SafetyStreamBuilder( stream: widget.stream, builder: (BuildContext context, String message) => Center( child: Text( message, style: TextStyle(fontSize: 30.0), ), ), ), ); CMBOL8JEHFUͱFSSPS8JEHFU͸ লུ͢Δ͜ͱ΋Մೳ ˞ॳظ஋͸ͦΕͧΕۭനͱ ʂ ϚʔΫ

Slide 20

Slide 20 text

ΦϨΦϨύοέʔδͷ ࡞Γํ

Slide 21

Slide 21 text

ίϚϯυҰൃͰϓϩδΣΫτ࡞੒ flutter create --template=package safety_stream_builder

Slide 22

Slide 22 text

࠷௿ݶඞཁͳ΋ͷ͸ɺશͯࣗಈੜ੒͞ΕΔ

Slide 23

Slide 23 text

ᶃίʔυΛॻ͘ᶄᶅॴ৴ද໌ ˡᶃίʔυ ˡᶄ࡞ऀ໊ͱ͔ ˡᶅʢॳճόʔδϣϯʹʣ ͲΜͳػೳ͕͋Δͱ͔

Slide 24

Slide 24 text

library safety_stream_builder; import 'dart:async'; import 'package:flutter/material.dart'; typedef Widget AsyncWidgetSafetyBuilder(BuildContext context, T data); typedef Widget BuildHandler(BuildContext context); class SafetyStreamBuilder extends StreamBuilder { static BuildHandler _buildErrorWidget = _defaultBuildErrorWidget; static BuildHandler _buildBlankWidget = _defaultBuildBlankWidget; final AsyncWidgetSafetyBuilder _builder; final Widget blankWidget; final Widget errorWidget; factory SafetyStreamBuilder({ @required AsyncWidgetSafetyBuilder builder, Key key, T initialData, Stream stream, Widget blankWidget, Widget errorWidget, }) => SafetyStreamBuilder._( builder: builder, unusedBuilder: (_, __) => null, // dummy key: key, initialData: initialData, stream: stream, blankWidget: blankWidget, errorWidget: errorWidget, ); SafetyStreamBuilder._({ @required AsyncWidgetSafetyBuilder builder, @required AsyncWidgetBuilder unusedBuilder, Key key, T initialData, Stream stream, this.blankWidget, this.errorWidget, }) : _builder = builder, super( key: key, initialData: initialData, stream: stream, builder: unusedBuilder, ); @override Widget build(BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return errorWidget != null ? errorWidget : _buildErrorWidget(context); } if (!snapshot.hasData) { return blankWidget != null ? blankWidget : _buildBlankWidget(context); } return _builder(context, snapshot.data); } static Widget _defaultBuildErrorWidget(BuildContext _) => const Icon(Icons.error_outline); static Widget _defaultBuildBlankWidget(BuildContext _) => Container(); static void handleError({@required BuildHandler build}) => _buildErrorWidget = build; static void handleBlank({@required BuildHandler build}) => _buildBlankWidget = build; } ᶃϑΝΠϧʹίʔυΛॻ͘

Slide 25

Slide 25 text

name: safety_stream_builder description: A new flutter package project. version: 0.0.1 author: kuronekomichael homepage: https://github.com/kuronekomichael/SafetyStreamBuilder environment: sdk: ">=2.0.0-dev.68.0 <3.0.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter: ᶄQVCTQFDZBNMʹɺ BVUIPSͱIPNFQBHFΛॻ͘

Slide 26

Slide 26 text

## v0.0.1 * Initial Release * No API Document ᶅ$)"/(&-0(NEʹɺ ϦϦʔεϊʔτΛॻ͘ ʢͳͯ͘΋ΠέΔ͚Ͳڐͤͳ͍ͷͰॻ͘ʣ

Slide 27

Slide 27 text

ᶃTBGFZ@TUSFBN@CVJMEFSEBSUॻ͍ͨ ᶄQVCTQFDZBNMʹ໊લॻ͍ͨ ᶅ$)"/(&-0(NEʹϦϦʔεϊʔτॻ͍ͨ Αʔ͠ શੈքʹެ։ͪ͠Ό͏ͧʂ

Slide 28

Slide 28 text

$ pub publish ↩

Slide 29

Slide 29 text

Pub needs your authorization to upload packages on your behalf. In a web browser, go to https:// accounts.google.com/o/oauth2/auth? access_type=offline&approval_prompt=force&re sponse_type=code&client_id=123456789- somethingsomethinganything.apps.googleuserco ntent.com&redirect_uri=http%3A%2F%2Flocalhos t%3A54569&scope=https%3A%2F%2Fwww.googleapis .com%2Fauth%2Fuserinfo.email Then click "Allow access". Waiting for your authorization... (PPHMFೝূ

Slide 30

Slide 30 text

IUUQTQVCEBSUMBOHPSHQBDLBHFTTBGFUZ@TUSFBN@CVJMEFS

Slide 31

Slide 31 text

IUUQTQVCEBSUMBOHPSHQBDLBHFTTBGFUZ@TUSFBN@CVJMEFS ଈެ։ʂʂʂ

Slide 32

Slide 32 text

·ͱΊ w QVCެ։Χϯλϯա͗řşΔXXXXXX w Ұ౓ެ։ͨ͠ύοέʔδ͸ɺݪଇͱͯ͠औΓԼ͛ෆՄ
 ʢউखʹऔΓԼ͛Δͱɺੈքதͷ୭͔ͷϓϩδΣΫτ͕ ಥવϏϧυΤϥʔʹͳΔ͔΋͠Εͳ͍ͷͰʣ w ͍·QVC͸ϒϧʔΦʔγϟϯͳͷͰνϟϯε

Slide 33

Slide 33 text

$ pub publish —dry-run ʲิ଍ʳ lESZSVOzΛ͚ͭΔͱɺ ެ։͢ΔલʹνΣοΫͰ͖·͢

Slide 34

Slide 34 text

શίʔυΛެ։ͯ͠·͢ IUUQTHJUIVCDPNLVSPOFLPNJDIBFM4BGFUZ4USFBN#VJMEFS