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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Daisuke Kishino
November 03, 2020
Programming
470
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
950
Ionicあらまし@okayama-js
kishino
0
1.1k
MonacaアプリをネイティブのUXに近づけるために
kishino
0
990
Sign In with Appleを実装してみた
kishino
0
450
Fluid interfaces for Monaca
kishino
0
260
Vue.jsの特徴
kishino
0
620
Monacaでアプリ名の多言語化
kishino
0
790
Other Decks in Programming
See All in Programming
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
430
Go × SIMDで高速化するベクトル検索 ~ルーフラインモデルでSIMDが効く境界を探れ! ~
po3rin
1
190
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
1
280
個人開発基盤をまるごとCloudflareに引っ越して爆速で総合的体験を向上させた話
tinykitten
0
140
[DroidKaigi 2026] Bring your own phones to Gradle Managed Devices
f2lk
0
110
スマート反転とウェブアクセシビリティ
camiha
0
170
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.7k
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
55
37k
不幸な GC
chencmd
0
890
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1k
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
360
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
470
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Making the Leap to Tech Lead
cromwellryan
135
10k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
710
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
Side Projects
sachag
456
43k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
820
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Become a Pro
speakerdeck
PRO
31
6.2k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
840
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
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৮ͬͯΈͯԼ͍͞ʂ