Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutterコンテストを開催した話

 Flutterコンテストを開催した話

Daisuke Kishino

November 03, 2020
Tweet

More Decks by Daisuke Kishino

Other Decks in Programming

Transcript

  1. 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ؔ਺͕ ࠶౓࣮ߦʢϦϏϧυʣ͞Ε ͕ඳը͞ΕΔ
  2. MaterialApp MainScreen EventDetailScreen EventsScreen GalleryScreen SettingsScreen ScrollablePositionedList EventListTile Text theme

    = light theme.textTheme TFU4UBUFͩͱ ࢠ8JEHFUʹ஋ UIFNF Λ ౉͍ͯ͘͠ඞཁ͕͋Δ
  3. 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ͱಉ͡Πϝʔδʣ
  4. 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
  5. ϦϏϧυͷ࠷దԽ 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ʣ ͱͯ͠ఆٛ
  6. 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
  7. 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ଆʹฦΔ