Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Flutterコンテストを開催した話
Search
Daisuke Kishino
November 03, 2020
Programming
460
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
980
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
Terraform標準の組織で AWS CDKをどう使うか
mu7889yoon
1
470
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
180
FDEが実現するAI駆動経営の現在地
gonta
2
250
メールのエイリアス機能を履き違えない
isshinfunada
0
210
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
350
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
450
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
200
仕様駆動開発の消費期限
watany
2
300
AI時代、エンジニアはどう育つのか -未経験エンジニアの成長を間近で見て考えたこと-
thasu0123
0
210
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
250
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
Featured
See All Featured
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
320
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
360
New Earth Scene 8
popppiees
3
2.5k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
370
The Curse of the Amulet
leimatthew05
2
13k
Side Projects
sachag
455
43k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
240
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Making the Leap to Tech Lead
cromwellryan
135
10k
It's Worth the Effort
3n
188
29k
Practical Orchestrator
shlominoach
191
12k
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৮ͬͯΈͯԼ͍͞ʂ