Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Flutterコンテストを開催した話
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Daisuke Kishino
November 03, 2020
Programming
480
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Flutterコンテストを開催した話
Daisuke Kishino
November 03, 2020
More Decks by Daisuke Kishino
See All by Daisuke Kishino
Monaca、WKWebViewに移行しようぜ!
kishino
0
960
Ionicあらまし@okayama-js
kishino
0
1.1k
MonacaアプリをネイティブのUXに近づけるために
kishino
0
1k
Sign In with Appleを実装してみた
kishino
0
450
Fluid interfaces for Monaca
kishino
0
270
Vue.jsの特徴
kishino
0
620
Monacaでアプリ名の多言語化
kishino
0
810
Other Decks in Programming
See All in Programming
ActionController meets Protocol Buffers
sorah
1
770
Crash Auto Pipelines
veronikapj
1
300
Coding with AI: How to trust the storyteller (AWS Community Day Adria, Ljubljana 2026)
slobodan
0
130
dotNET_vulnclicker_intro.pdf
deka_morita
0
160
JIS keyboard support in Omarchy
lef237
0
180
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
180
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
350
조합이폭발하는디자인시스템이걸눈으로도테스트하라고요
giljongyu
0
690
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
180
ChromeでローカルLLM
ryu1013
0
190
私なりのハーネスエンジニアリング ~独自の言語処理系の開発を通して~
seosoft
0
160
TanStack Vue Query と Pinia Colada から学ぶ非同期状態の型設計
aoshi
0
580
Featured
See All Featured
Code Review Best Practice
trishagee
74
20k
Rails Girls Zürich Keynote
gr2m
96
14k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
520
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
390
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
960
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
sira's awesome portfolio website redesign presentation
elsirapls
0
480
Ten Tips & Tricks for a 🌱 transition
stuffmc
1
280
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Typedesign – Prime Four
hannesfritz
42
3.2k
Transcript
'MVUUFSίϯςετΛ։࠵ͨ͠ %BJTVLF,JTIJOP ߹ಉษڧձJOେձԬࢁ8JOUFS0OMJOF
ࣗݾհ w ϐʔϓϧιϑτΣΞגࣜձࣾ w ؛େีʢ!LJTIJTVLFʣ w Ԭࢁݝෑࢢࡏॅ w ͜͜εϚϗΞϓϦ։ൃ͕ϝΠϯ ʢ.POBDBɺ7VFKTɺ4XJGUͱ͔ʣ
w .POBDB6(0,":"."ͬͯ·͢
ࠓ͢͜ͱ wࣗࣾͰ'MVUUFSΞϓϦίϯςετΛߦͬͨ wࢀՃऀͱͯࣗ͠'MVUUFSΞϓϦΛॳΊͯຊ࡞ͬͨ wίϯςετͷऔΓΈ'MVUUFSͷհΛߦ͍ͭͭɺ࡞ͬͨ ΞϓϦͰͷܦݧΛ͓͠·͢
'MVUUFSͱʁ w(PPHMF͕։ൃ͍ͯ͠ΔΫϩεϓϥοτϑΥʔϜΞϓϦ։ൃπʔϧ w8JEHFUπϦʔͰ6*Λߏஙʢ3FBDUɺ7VFͷԾ%0.ಉ͡Πϝʔδʣ w4LJBͰϨϯμϦϯάΛߦ͏ʢωΠςΟϒͷ6*ίϯϙʔωϯτʹґଘ͍ͯ͠ ͳ͍ʣ w։ൃݴޠ%BSU w։ൃத%BSU7.ʹΑΔ)PU3FMPBEͰߴ։ൃ wετΞެ։࣌"05Ͱߴಈ࡞
'MVUUFSίϯςετ։࠵ͷ͖͔͚ͬ w'MVUUFSؒΛ૿ͯ͠։ൃͷϞνϕʔγϣϯ্͍͛ͨɻ͔͠͠ɺதʑ ू·Βͳ͍ʜ wۚग़ͯ͠ίϯςετΛ։࠵ͨ͠Βू·Δ͔ʁ wͪͳΈʹओ࠵ऀผͷํͰ͢ wࢲٕज़αϙʔτͱ͍͏ׂʢॳ৺ऀͳͷʹαϙʔτͱͳʁʣ
'MVUUFSίϯςετΛ։࠵͢ΔϝϦοτ w'MVUUFSͷٕज़ऀ͕૿͑Δʂ wࣾΠϕϯτͷࢀՃऀ͕૿͑Δʂʂ wձࣾͷΞϐʔϧʹͳΔʂʂʂ
'MVUUFSίϯςετͷ֓ཁ wԠืظؒࠓͷʙ݄ w։ൃ༻ͷ"OESPJEΛ wษڧձ4MBDLͰϑΥϩʔΞοϓ wදজɺΞΠσΞɺ69ɺ༗ӹੑͷΧςΰϦʔͱάϥϯϓϦ wਓͷΤϯτϦʔʂʢఏग़͕͋ͬͨͷΞϓϦʣ w৽ਓ໊ʴϕςϥϯ໊Ͱ৹ࠪ wۚ͋Γʢձࣾ࣋ͪʣ wͦͷଞɺৄࡉҎԼهࣄͰհ͍ͯ͠·͢ʂ wIUUQTUFDIQTDTSWDPKQࣾΞϓϦίϯςετΛ࣮ࢪͯ͠Έͯ
࡞ͬͨΞϓϦͷհ wٯΊ͘ΓΧϨϯμʔ w͋ͱԿ͔ͳʁΛָ͘͢͠ΔΧϯτμ ϯΞϓϦ wखಈͰΊ͘Γ͢Δ6*ͳͷ͕ಛ w࣮ੲϦϦʔεͯͨ͠ΞϓϦͷϦϝΠΫ wͪͳΈʹࢲ͍͖ͨͩ·ͨ͠
͔͜͜Βٕज़తͳͰ͢ ΞϓϦΛ࢝Ίͯ࡞ͬͯΈͯɺ͜͜ॏཁͩͳ ͱࢥͬͨͱ͜ΖͳͲΛϐοΫΞοϓ͠·ͨ͠
ঢ়ଶཧ wঢ়ଶཧʢ7VFKTͰ͍͏ͱ͜ΖͷEBUB7VFYʣͲ͏͢ΔΜͩΖ͏ʁ w#-P$ͱ͔4UBUF/PUJGJFSͱ͔ɺ͍Ζ͍ΖΓํ͕͋ΔΈ͍͚ͨͩͲʜ
ঢ়ଶཧ w·ͣγϯϓϧʹ4UBUFGVM8JEHFUͱTFU4UBUFͰ࣮ w4UBUFGVM8JEHFU4UBUFʢঢ়ଶʣΛ࣋ͭ8JEHFU wঢ়ଶΛ࣋ͨͳ͍4UBUFMFTT8JEHFU͋Δ w4UBUFͷใΛͱʹ8JEHFUΛߏங͢Δ
class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState();
} class _MyHomePageState extends State<MyHomePage> { 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͕ؔ ࠶࣮ߦʢϦϏϧυʣ͞Ε ͕ඳը͞ΕΔ
ঢ়ଶཧ w4UBUFGVM8JEHFUͱTFU4UBUFγϯϓϧͰ͔Γ͍͢ w͔͠͠ɺ8JEHFUͷ֊͕ਂ͘ͳΔͱTFU4UBUFͰݫ͘͠ͳͬͯ͘Δ wྫ͑ɺμʔΫϞʔυͷมߋͱ͔
MaterialApp MainScreen EventDetailScreen EventsScreen GalleryScreen SettingsScreen ScrollablePositionedList EventListTile Text theme
= light theme.textTheme TFU4UBUFͩͱ ࢠ8JEHFUʹ UIFNF Λ ͍ͯ͘͠ඞཁ͕͋Δ
ঢ়ଶཧʢ1SPWJEFSͱ$IBOHF/PUJGJFSʣ Ұ෦ͷঢ়ଶཧΛ1SPWJEFSͱ$IBOHF/PUJGJFSͷΈ߹Θͤʹมߋ w1SPWJEFS w%*ͷΈΛఏڙ͢ΔެࣜϥΠϒϥϦ w4UBUFΛࢠ8JEHFUʹೖ͢Δ͜ͱͰঢ়ଶཧʹ͑Δ w$IBOHF/PUJGJFS w͕มߋ͞Εͨ͜ͱΛࢠ8JEHFUʹ͑ΔͨΊͷΈʢΫϥεʣ wTFU4UBUFతͳׂ
MaterialApp MainScreen EventDetailScreen EventsScreen GalleryScreen SettingsScreen ScrollablePositionedList EventListTile Text theme
= light theme.textTheme .BUFSJBM"QQ͕࣋ͭ UIFNFΛࢀরͰ͖Δ
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ͱಉ͡Πϝʔδʣ
void main() { runApp( ChangeNotifierProvider( create: (_) => AppThemeController() )
); } Widget build(BuildContext context) { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: context.select<AppThemeController, Color>( (value) => value.theme.highlightColor), ), child: Column(children: children), ); } શମͰࢀর͍ͨ͠ͷͰ ϧʔτͰఆٛ ֤8JEHFUͰ 4UBUF UIFNF Λࢀর $IBOHF/PUJGJFSΛࢀর ͢ΔͨΊͷ1SPWJEFS
ঢ়ଶཧ w1SPWJEFSͷସͱͯ͠3FWFSQPE w$IBOHF/PUJGJFSͷସͱͯ͠4UBUF/PUJGJFS ͱ͍͏ͷ͋Δ 4UBUFGVM8JEHFU TFU4UBUF 1SPWJEFS $IBOHF/PUJGJFS
1SPWJEFSPS3FWFSQPE 4UBUF/PUJGJFS ͷॱͰ͍֮͑ͯ͘ͱྑͦ͞͏ͩͱײͨ͡
ΧϨϯμʔΛΊ͘Δ6*͕ΧΫπΫʜ wΧϨϯμʔΛΊ͘Δ6*ࢦΛಈ͔͢ ʹ8JEHFUͷϦϏϧυΛߦ͍ͬͯΔ͔Β ෛՙ͕͔͔͍ͬͯΔʁ
ϦϏϧυͷ࣮ߦίετ wϦϏϧυ͞Εͨ8JEHFUπϦʔΛͱʹɺ6*ͷϨΠΞτͱඳը͕ߦΘΕ Δ w6*ͷϨΠΞτͱඳըࠩө͞ΕΔ w3FBDU7VFͷԾ%0.ͱ%0.ͷΠϝʔδ w8JEHFUߏใΛ࣋ͭ୯ͳΔΠϯελϯεͳͷͰɺੜίετ͍
ϦϏϧυͷ࠷దԽΛ͖͢ύλʔϯ wΞχϝʔγϣϯͳͲͰ͍࣌ؒͰ͔ͳΓͷճ ϦϏϧυ͕࣮ߦ͞ΕΔ߹ཁҙ wΧϨϯμʔΛΊ͘Δ6*ͦͷύλʔϯ wϦϏϧυΊ͘Δ6*෦͚ͩͰͳ͘ɺϖʔ δશମͰߦΘΕΔͨΊ݁ߏߴίετʹͳΔ w࠷దԽ͠ͳͪ͘Όʢ໋ײʣ
ϦϏϧυ͞Ε͍ͯΔՕॴ Ί͘Δ6*ͷ8JEHFU ΧϨϯμʔ6*ͷ8JEHFU ʢؔͳ͍ͱ͜Ζ·Ͱ ϦϏϧυ͞Ε͍ͯΔ ʣ
ϦϏϧυͷ࠷దԽ Widget build(BuildContext context) { return Container( height: height, child:
Stack( overflow: Overflow.clip, children: <Widget>[ const _EventPageMain(), Transform.translate( //... ) ], ), ); } Widget build(BuildContext context) { return Container( height: height, child: Stack( overflow: Overflow.clip, children: <Widget>[ Positioned( //... ), Transform.translate( //... ) ], ), ); } ผ8JEHFUʹ͚ͯɺ ίϯύΠϧ࣌ఆʢDPOTUʣ ͱͯ͠ఆٛ
class _EventPageMain extends StatelessWidget { const _EventPageMain(); @override Widget build(BuildContext
context) { final event = context .select<EventDetailScreenController, Event>((value) => value.event); final eventDate = context .select<EventPageController, EventDate>((value) => value.eventDate); final eventCaptureKey = context.select<EventPageController, GlobalKey>( (value) => value.eventCaptureKey); // Ί͘Γ࣌ʹϦϏϧυ͢ΔͨΊɺselect͓ͯ͘͠ context.select<EventDetailScreenController, DateTime>( (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
Ί͘Δ6*ͷ8JEHFU ΧϨϯμʔ6*ͷ8JEHFU ʢϦϏϧυ͞Εͯͳ͍ ʣ ΧϨϯμʔ6*ͷ8JEHFU ʢϦϏϧυ͞Εͯͳ͍ ʣ
1MVHJOΛ࡞Δ wࣗࣾαʔϏεʢ#BB4!SBLV[Bʣ͍͍ͨ wωΠςΟϒͷ"1*ʹΞΫηε͢Δ߹1MVHJOΛ͏ʢͳ͍ͷͰ࡞ͬͨʣ
static const MethodChannel _channel = MethodChannel('baasatrakuza_flutter'); MethodChannel get channel =>
_channel; @override Future<Data> getData(String objectId, String code) async { final data = await channel.invokeMapMethod<String, dynamic>( 'getData', {'objectId': objectId, 'code': code}); return Data.fromMap(data); } fun getData(call: MethodCall, result: MethodChannel.Result) { val objectId = call.argument<String>("objectId") val code = call.argument<String>("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ଆʹฦΔ
1MVHJOͲ͏ͳΜʁ wόΠτྻͰσʔλͷΓͱΓͰ͖ΔͨΊΦʔόʔϔουগͳͦ͏ʢ+40/Մೳʣ wࠓճ༻͍ͯ͠ͳ͍͕ɺ1MBUGPSN7JFXΛͬͯωΠςΟϒͷ6*ίϯϙʔωϯτΛ ඳը͢Δ͜ͱՄೳʢHPPHMF@NBQT@GMVUUFSͳͲʣ wৄࡉҎԼΛࢀর͍ͩ͘͞ʂ wIUUQTUFDIQTDTSWDPKQCBBTSBLV[BͷGMVUUFSTEL։ൃத
ศརͳϥΠϒϥϦΛ୳͢ wQVCEFWͰ୳͢
ྫ TDSPMMBCMF@QPTJUJPOFE@MJTU wઌ಄ͷΧϨϯμʔͷ݄͕มΘͬͨΒλΠτϧ ʢ݄ʣม͑Δ wΧϨϯμʔλϒΛλοϓ͢ΔͱɺࠓͷҐஔʹ εΫϩʔϧ͢Δ wͳͲɺඪ४ͷ-JTU7JFXͩͱ͍͠εΫϩʔϧॲ ཧΛ؆୯ʹ࣮Ͱ͖Δ
ίϯςετͰ'MVUUFSΞϓϦ࡞ͬͯΈͯ w'MVUUFSͷධՁ wੜ࢈ੑߴ͍ɻ)PU3FMPBE͕ΊͬͪΌศར wֶशίετߴ͍ͱݴΘΕΔ͕ɺ3FBDU7VFͳͲͷએݴత6*ͷ։ൃʹ׳Ε͍ͯΕ ͦΕ΄ͲͰͳ͍ʢ%BSU4XJGUͱ͔5ZQF4DSJQU͍ͬͯΕͳ͠ʣ w༗༻ͳϥΠϒϥϦ͕ଟ͘ɺ৽͍͠ڥͷΘΓʹॆ࣮͍ͯ͠Δ wίϯςετ wΞϓϦ࡞Γͳ͕Βͩͱ֮͑Δͷ͕ૣ͍ʢ͋ͱ ͷϞνϕʔγϣϯʣ wҰॹʹ࡞Δਓ͕͍ΔͱϞνϕʔγϣϯ্͕͕Δ
wίϯςετܦݧऀΛ૿͢ྑ͍ࢪࡦ͔
࠷ޙʹ
'MVUUFS։ൃऀΛ૿͍ͨ͠ w'MVUUFSૉΒ͍ٕ͠ज़͕ͩɺ8FCωΠςΟϒܥͷΤίγεςϜʢͱ ΓΘ͚ٕज़ऀʣΛͦͷ··औΓࠐΊͳ͍ wͦ͜ͰɺࣾͰ·ٕͣज़ऀΛ૿ͨ͢ΊʹίϯςετΛ։࠵ wԬࢁશମͰٕज़ऀΛ૿͍͖͍ͯͨ͠ wͱࢥͬͯɺ͓͍͖ͤͯͨͩ͠͞·ͨ͠ wڵຯ͕͋Εͥͻ'MVUUFS৮ͬͯΈͯԼ͍͞ʂ