Slide 1

Slide 1 text

'MVUUFSίϯςετΛ։࠵ͨ͠࿩ %BJTVLF,JTIJOP ߹ಉษڧձJOେ౎ձԬࢁ8JOUFS0OMJOF

Slide 2

Slide 2 text

ࣗݾ঺հ w ϐʔϓϧιϑτ΢ΣΞגࣜձࣾ w ؛໺େีʢ!LJTIJTVLFʣ w Ԭࢁݝ૔ෑࢢࡏॅ w ͜͜೥͸εϚϗΞϓϦ։ൃ͕ϝΠϯ ʢ.POBDBɺ7VFKTɺ4XJGUͱ͔ʣ w .POBDB6(0,":"."΍ͬͯ·͢

Slide 3

Slide 3 text

ࠓ೔࿩͢͜ͱ wࣗࣾͰ'MVUUFSΞϓϦίϯςετΛߦͬͨ wࢀՃऀͱͯࣗ͠਎΋'MVUUFSΞϓϦΛॳΊͯຊ࡞ͬͨ wίϯςετͷऔΓ૊Έ΍'MVUUFSͷ঺հΛߦ͍ͭͭɺ࡞ͬͨ ΞϓϦͰͷܦݧΛ͓࿩͠·͢

Slide 4

Slide 4 text

'MVUUFSͱ͸ʁ w(PPHMF͕։ൃ͍ͯ͠ΔΫϩεϓϥοτϑΥʔϜΞϓϦ։ൃπʔϧ w8JEHFUπϦʔͰ6*Λߏஙʢ3FBDUɺ7VFͷԾ૝%0.ಉ͡Πϝʔδʣ w4LJBͰϨϯμϦϯάΛߦ͏ʢωΠςΟϒͷ6*ίϯϙʔωϯτʹґଘ͍ͯ͠ ͳ͍ʣ w։ൃݴޠ͸%BSU w։ൃத͸%BSU7.ʹΑΔ)PU3FMPBEͰߴ଎։ൃ wετΞެ։࣌͸"05Ͱߴ଎ಈ࡞

Slide 5

Slide 5 text

'MVUUFSίϯςετ։࠵ͷ͖͔͚ͬ w'MVUUFS஥ؒΛ૿΍ͯ͠։ൃͷϞνϕʔγϣϯ্͍͛ͨɻ͔͠͠ɺதʑ ू·Βͳ͍ʜ w৆ۚग़ͯ͠ίϯςετΛ։࠵ͨ͠Βू·Δ͔΋ʁ wͪͳΈʹओ࠵ऀ͸ผͷํͰ͢ wࢲ͸ٕज़αϙʔτͱ͍͏໾ׂʢॳ৺ऀͳͷʹαϙʔτͱͳʁʣ

Slide 6

Slide 6 text

'MVUUFSίϯςετΛ։࠵͢ΔϝϦοτ w'MVUUFSͷٕज़ऀ͕૿͑Δʂ wࣾ಺Πϕϯτ΁ͷࢀՃऀ͕૿͑Δʂʂ wձࣾͷΞϐʔϧʹͳΔʂʂʂ

Slide 7

Slide 7 text

'MVUUFSίϯςετͷ֓ཁ wԠืظؒ͸ࠓ೥ͷʙ݄ w։ൃ༻ͷ"OESPJE୺຤Λ഑෍ wษڧձ΍4MBDLͰϑΥϩʔΞοϓ wදজ͸׬੒౓ɺΞΠσΞɺ69ɺ༗ӹੑͷΧςΰϦʔ৆ͱάϥϯϓϦ wਓͷΤϯτϦʔʂʢఏग़͕͋ͬͨͷ͸ΞϓϦʣ w৽ਓ໊ʴϕςϥϯ໊Ͱ৹ࠪ w৆ۚ͋Γʢձࣾ࣋ͪʣ wͦͷଞɺৄࡉ͸ҎԼهࣄͰ঺հ͍ͯ͠·͢ʂ wIUUQTUFDIQTDTSWDPKQࣾ಺ΞϓϦίϯςετΛ࣮ࢪͯ͠Έͯ

Slide 8

Slide 8 text

࡞ͬͨΞϓϦͷ঺հ wٯ೔Ί͘ΓΧϨϯμʔ w͋ͱԿ೔͔ͳʁΛָ͘͢͠ΔΧ΢ϯτμ΢ ϯΞϓϦ wखಈͰ೔Ί͘Γ͢Δ6*ͳͷ͕ಛ௃ w࣮͸ੲϦϦʔεͯͨ͠ΞϓϦͷϦϝΠΫ wͪͳΈʹࢲ͸׬੒౓৆͍͖ͨͩ·ͨ͠

Slide 9

Slide 9 text

͔͜͜Β͸ٕज़తͳ࿩Ͱ͢ ΞϓϦΛ࢝Ίͯ࡞ͬͯΈͯɺ͜͜͸ॏཁͩͳ ͱࢥͬͨͱ͜ΖͳͲΛϐοΫΞοϓ͠·ͨ͠

Slide 10

Slide 10 text

ঢ়ଶ؅ཧ wঢ়ଶ؅ཧʢ7VFKTͰ͍͏ͱ͜ΖͷEBUB΍7VFYʣ͸Ͳ͏͢ΔΜͩΖ͏ʁ w#-P$ͱ͔4UBUF/PUJGJFSͱ͔ɺ͍Ζ͍Ζ΍Γํ͕͋ΔΈ͍͚ͨͩͲʜ

Slide 11

Slide 11 text

ঢ়ଶ؅ཧ w·ͣ͸γϯϓϧʹ4UBUFGVM8JEHFUͱTFU4UBUFͰ࣮૷ w4UBUFGVM8JEHFU͸4UBUFʢঢ়ଶʣΛ࣋ͭ8JEHFU wঢ়ଶΛ࣋ͨͳ͍4UBUFMFTT8JEHFU΋͋Δ w4UBUFͷ৘ใΛ΋ͱʹ8JEHFUΛߏங͢Δ

Slide 12

Slide 12 text

class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text( '$_counter', style: Theme.of(context).textTheme.headline4, ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, child: Icon(Icons.add), ), ); } } ᶃ4UBUFGVM8JEHFU͕ 4UBUFΛੜ੒͢Δ ᶄ4UBUFͰ8JEHFUΛߏங ᶅ࠷ॳ͸Ͱඳը͞ΕΔ ᶆʴϘλϯΛλοϓ࣌ʹ TFU4UBUFʹ౉ͨؔ͠਺ͷதͰ ม਺ΛΠϯΫϦϝϯτ ᶇCVJMEؔ਺͕ ࠶౓࣮ߦʢϦϏϧυʣ͞Ε ͕ඳը͞ΕΔ

Slide 13

Slide 13 text

ঢ়ଶ؅ཧ w4UBUFGVM8JEHFUͱTFU4UBUF͸γϯϓϧͰ෼͔Γ΍͍͢ w͔͠͠ɺ8JEHFUͷ֊૚͕ਂ͘ͳΔͱTFU4UBUFͰ͸ݫ͘͠ͳͬͯ͘Δ wྫ͑͹ɺμʔΫϞʔυ΁ͷมߋͱ͔

Slide 14

Slide 14 text

MaterialApp MainScreen EventDetailScreen EventsScreen GalleryScreen SettingsScreen ScrollablePositionedList EventListTile Text theme = light theme.textTheme TFU4UBUFͩͱ ࢠ8JEHFUʹ஋ UIFNF Λ ౉͍ͯ͘͠ඞཁ͕͋Δ

Slide 15

Slide 15 text

ঢ়ଶ؅ཧʢ1SPWJEFSͱ$IBOHF/PUJGJFSʣ Ұ෦ͷঢ়ଶ؅ཧΛ1SPWJEFSͱ$IBOHF/PUJGJFSͷ૊Έ߹Θͤʹมߋ w1SPWJEFS w%*ͷ࢓૊ΈΛఏڙ͢ΔެࣜϥΠϒϥϦ w4UBUFΛࢠ8JEHFUʹ஫ೖ͢Δ͜ͱͰঢ়ଶ؅ཧʹ΋࢖͑Δ w$IBOHF/PUJGJFS w஋͕มߋ͞Εͨ͜ͱΛࢠ8JEHFUʹ఻͑ΔͨΊͷ࢓૊ΈʢΫϥεʣ wTFU4UBUFతͳ໾ׂ

Slide 16

Slide 16 text

MaterialApp MainScreen EventDetailScreen EventsScreen GalleryScreen SettingsScreen ScrollablePositionedList EventListTile Text theme = light theme.textTheme .BUFSJBM"QQ͕࣋ͭ UIFNFΛ௚઀ࢀরͰ͖Δ

Slide 17

Slide 17 text

class AppThemeController extends ChangeNotifier { AppTheme _lightTheme; AppTheme _darkTheme; AppThemeMode _themeMode; AppTheme get theme => _themeMode == AppThemeMode.light ? _lightTheme : _darkTheme; void setThemeMode(AppThemeMode themeMode) { _themeMode = themeMode; notifyListeners(); } } $IBOHF/PUJGJFSΛܧঝ͠ ͨΫϥεʹ4UBUFΛ࣋ͭ 4UBUFΛม͑ͨΒ OPUJGZ-JTUFOFSTΛݺͼग़͢ ʢTFU4UBUFͱಉ͡Πϝʔδʣ

Slide 18

Slide 18 text

void main() { runApp( ChangeNotifierProvider( create: (_) => AppThemeController() ) ); } Widget build(BuildContext context) { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: context.select( (value) => value.theme.highlightColor), ), child: Column(children: children), ); } શମͰࢀর͍ͨ͠ͷͰ ϧʔτͰఆٛ ֤8JEHFUͰ 4UBUF UIFNF Λࢀর $IBOHF/PUJGJFSΛࢀর ͢ΔͨΊͷ1SPWJEFS

Slide 19

Slide 19 text

ঢ়ଶ؅ཧ w1SPWJEFSͷ୅ସͱͯ͠3FWFSQPE w$IBOHF/PUJGJFSͷ୅ସͱͯ͠4UBUF/PUJGJFS ͱ͍͏ͷ΋͋Δ 4UBUFGVM8JEHFUTFU4UBUF 1SPWJEFS$IBOHF/PUJGJFS 1SPWJEFSPS3FWFSQPE4UBUF/PUJGJFS ͷॱͰ͍֮͑ͯ͘ͱྑͦ͞͏ͩͱײͨ͡

Slide 20

Slide 20 text

ΧϨϯμʔΛΊ͘Δ6*͕ΧΫπΫʜ wΧϨϯμʔΛΊ͘Δ6*͸ࢦΛಈ͔͢౓ ʹ8JEHFUͷϦϏϧυΛߦ͍ͬͯΔ͔Β ෛՙ͕͔͔͍ͬͯΔʁ

Slide 21

Slide 21 text

ϦϏϧυͷ࣮ߦίετ wϦϏϧυ͞Εͨ8JEHFUπϦʔΛ΋ͱʹɺ6*ͷϨΠΞ΢τͱඳը͕ߦΘΕ Δ w6*ͷϨΠΞ΢τͱඳը͸ࠩ෼൓ө͞ΕΔ w3FBDU΍7VFͷԾ૝%0.ͱ%0.ͷΠϝʔδ w8JEHFU͸ߏ੒৘ใΛ࣋ͭ୯ͳΔΠϯελϯεͳͷͰɺੜ੒ίετ͸௿͍

Slide 22

Slide 22 text

ϦϏϧυͷ࠷దԽΛ͢΂͖ύλʔϯ wΞχϝʔγϣϯͳͲͰ୹͍࣌ؒͰ͔ͳΓͷճ ਺ϦϏϧυ͕࣮ߦ͞ΕΔ৔߹͸ཁ஫ҙ wΧϨϯμʔΛΊ͘Δ6*΋ͦͷύλʔϯ wϦϏϧυ͸Ί͘Δ6*෦෼͚ͩͰ͸ͳ͘ɺϖʔ δશମͰߦΘΕΔͨΊ݁ߏߴίετʹͳΔ w࠷దԽ͠ͳͪ͘Όʢ࢖໋ײʣ

Slide 23

Slide 23 text

ϦϏϧυ͞Ε͍ͯΔՕॴ Ί͘Δ6*ͷ8JEHFU ΧϨϯμʔ6*ͷ8JEHFU ʢؔ܎ͳ͍ͱ͜Ζ·Ͱ ϦϏϧυ͞Ε͍ͯΔ ʣ

Slide 24

Slide 24 text

ϦϏϧυͷ࠷దԽ Widget build(BuildContext context) { return Container( height: height, child: Stack( overflow: Overflow.clip, children: [ const _EventPageMain(), Transform.translate( //... ) ], ), ); } Widget build(BuildContext context) { return Container( height: height, child: Stack( overflow: Overflow.clip, children: [ Positioned( //... ), Transform.translate( //... ) ], ), ); } ผ8JEHFUʹ෼͚ͯɺ ίϯύΠϧ࣌ఆ਺ʢDPOTUʣ ͱͯ͠ఆٛ

Slide 25

Slide 25 text

class _EventPageMain extends StatelessWidget { const _EventPageMain(); @override Widget build(BuildContext context) { final event = context .select((value) => value.event); final eventDate = context .select((value) => value.eventDate); final eventCaptureKey = context.select( (value) => value.eventCaptureKey); // ೔Ί͘Γ࣌ʹϦϏϧυ͢ΔͨΊɺselect͓ͯ͘͠ context.select( (value) => value.event.lastTearOffDate); final statusBarHeight = Device.instance.statusBarHeight; final textColor = getEventTextColor(event, eventDate); final width = MediaQuery.of(context).size.width; return Positioned( //... ); } } 4UBUFMFTT8JEHFUΛܧঝ ίϯετϥΫλͷύϥϝʔ λʔ͕શͯDPOTUͰ͋Δඞཁ ͕͋ΔͨΊɺঢ়ଶ͸1SPWJEFS ͔Βऔಘ ίϯετϥΫλʹ΋DPOTU

Slide 26

Slide 26 text

Ί͘Δ6*ͷ8JEHFU ΧϨϯμʔ6*ͷ8JEHFU ʢϦϏϧυ͞Εͯͳ͍ ʣ ΧϨϯμʔ6*ͷ8JEHFU ʢϦϏϧυ͞Εͯͳ͍ ʣ

Slide 27

Slide 27 text

1MVHJOΛ࡞Δ wࣗࣾαʔϏεʢ#BB4!SBLV[Bʣ࢖͍͍ͨ wωΠςΟϒͷ"1*ʹΞΫηε͢Δ৔߹͸1MVHJOΛ࢖͏ʢͳ͍ͷͰ࡞ͬͨʣ

Slide 28

Slide 28 text

static const MethodChannel _channel = MethodChannel('baasatrakuza_flutter'); MethodChannel get channel => _channel; @override Future getData(String objectId, String code) async { final data = await channel.invokeMapMethod( 'getData', {'objectId': objectId, 'code': code}); return Data.fromMap(data); } fun getData(call: MethodCall, result: MethodChannel.Result) { val objectId = call.argument("objectId") val code = call.argument("code") this.client.getData(objectId, code) { data, rkzResponseStatus -> if (rkzResponseStatus.isSuccess) { result.success(exportObject(data)) } else { result.error(rkzResponseStatus.statusCode, rkzResponseStatus.message, null) } } } Dart (Flutter) Kotlin (Android) ωΠςΟϒଆͷॲཧ͸ .FUIPE$IBOOFMΛհͯ͠ ݺͼग़͢ .FUIPE$IBOOFM3FTVMUʹ݁ ՌΛ౉͢ͱ%BSUଆʹฦΔ

Slide 29

Slide 29 text

1MVHJOͲ͏ͳΜʁ wόΠτྻͰσʔλͷ΍ΓͱΓͰ͖ΔͨΊΦʔόʔϔου͸গͳͦ͏ʢ+40/΋Մೳʣ wࠓճ͸࢖༻͍ͯ͠ͳ͍͕ɺ1MBUGPSN7JFXΛ࢖ͬͯωΠςΟϒͷ6*ίϯϙʔωϯτΛ ඳը͢Δ͜ͱ΋ՄೳʢHPPHMF@NBQT@GMVUUFSͳͲʣ wৄࡉ͸ҎԼΛࢀর͍ͩ͘͞ʂ wIUUQTUFDIQTDTSWDPKQCBBTSBLV[BͷGMVUUFSTEL։ൃத

Slide 30

Slide 30 text

ศརͳϥΠϒϥϦΛ୳͢ wQVCEFWͰ୳͢

Slide 31

Slide 31 text

ྫ TDSPMMBCMF@QPTJUJPOFE@MJTU wઌ಄ͷΧϨϯμʔͷ݄͕มΘͬͨΒλΠτϧ ʢ೥݄ʣ΋ม͑Δ wΧϨϯμʔλϒΛλοϓ͢Δͱɺࠓ೔ͷҐஔʹ εΫϩʔϧ͢Δ wͳͲɺඪ४ͷ-JTU7JFXͩͱ೉͍͠εΫϩʔϧॲ ཧΛ؆୯ʹ࣮૷Ͱ͖Δ

Slide 32

Slide 32 text

ίϯςετͰ'MVUUFSΞϓϦ࡞ͬͯΈͯ w'MVUUFSͷධՁ wੜ࢈ੑ͸ߴ͍ɻ)PU3FMPBE͕ΊͬͪΌศར wֶशίετ͸ߴ͍ͱݴΘΕΔ͕ɺ3FBDU΍7VFͳͲͷએݴత6*ͷ։ൃʹ׳Ε͍ͯΕ ͹ͦΕ΄ͲͰ΋ͳ͍ʢ%BSU͸4XJGUͱ͔5ZQF4DSJQU஌͍ͬͯΕ͹໰୊ͳ͠ʣ w༗༻ͳϥΠϒϥϦ͕ଟ͘ɺ৽͍͠؀ڥͷΘΓʹॆ࣮͍ͯ͠Δ wίϯςετ wΞϓϦ࡞Γͳ͕Βͩͱ֮͑Δͷ͕ૣ͍ʢ͋ͱ ͷϞνϕʔγϣϯʣ wҰॹʹ࡞Δਓ͕͍ΔͱϞνϕʔγϣϯ্͕͕Δ wίϯςετ͸ܦݧऀΛ૿΍͢ྑ͍ࢪࡦ͔΋

Slide 33

Slide 33 text

࠷ޙʹ

Slide 34

Slide 34 text

'MVUUFS։ൃऀΛ૿΍͍ͨ͠ w'MVUUFS͸ૉ੖Β͍ٕ͠ज़͕ͩɺ8FC΍ωΠςΟϒܥͷΤίγεςϜʢͱ ΓΘ͚ٕज़ऀʣΛͦͷ··औΓࠐΊͳ͍ wͦ͜Ͱɺࣾ಺Ͱ·ٕͣज़ऀΛ૿΍ͨ͢ΊʹίϯςετΛ։࠵ wԬࢁશମͰ΋ٕज़ऀΛ૿΍͍͖͍ͯͨ͠ wͱࢥͬͯɺ͓࿩͍͖ͤͯͨͩ͠͞·ͨ͠ wڵຯ͕͋Ε͹ͥͻ'MVUUFS৮ͬͯΈͯԼ͍͞ʂ