Flutterå ¥é - ç°¡åãªã¢ããªãäœã£ãŠUI宣èšãããããªããŒããªã©äŸ¿å©æ©èœã®äœ¿ãæ¹ãçè§£ããã
ã¢ãã€ã«åãã¢ããªã±ãŒã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯ã»Flutterã䜿ã£ãŠç°¡åãªã¢ããªã±ãŒã·ã§ã³ãäœæããåºæ¬çãªéçºã«ã€ããŠãFlutterã®Google Developers Expertã§ããäžç°å²åºããã«è§£èª¬ããŠããã ããŸããã
ããã«ã¡ã¯ãäžç°å²åºïŒ@najeiraïŒã§ããFlutterã®Google Developers ExpertãšããŠæŽ»åããŠããŸãã
Flutterã¯ãGoogleãäžå¿ãšãªã£ãŠGitHubäžã§ãªãŒãã³ãœãŒã¹ãªãããžã§ã¯ããšããŠéçºãããŠãããã¢ãã€ã«åãã¢ããªã±ãŒã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯ã§ããAndroidãšiOSã®ã¢ããªãåäžã®ã³ãŒãããŒã¹ã§éçºã§ããŸãã
â»Webããã¹ã¯ããããžã®ãµããŒããä»åŸã®ããŒããããã«å«ãŸããŠããŸãã
Flutterã®ã¢ããªã¯Dartèšèªã䜿ã£ãŠèšè¿°ããŸããã¢ãã³ã§ReactiveãªUIãã¬ãŒã ã¯ãŒã¯ã§ãçŸããUI矀ãè±å¯ã«å«ãŸããŠããŸããFlutterã§ã¯UIã®åéšåã®ããšãWidgetãšåŒã³ãŸãã
ç¹é·ãšããŠã宣èšçãªUIå®çŸ©ãããããªããŒãïŒãã¡ã€ã«ã®å€æŽã»ä¿åããããšãªããŒãããããšãªããªã¢ã«ã¿ã€ã ã§ãã¡ã€ã«ãèªã¿èŸŒã¿çŽãæ©èœïŒã«ããé«ãéçºå¹çããªãªãŒã¹æã®ãã€ãã£ãã³ãŒããžã®äºåã³ã³ãã€ã«ã»GPUãæŽ»çšããã¬ã³ããªã³ã°ãšã³ãžã³ã«ããé«ãå®è¡ããã©ãŒãã³ã¹ãªã©ããããŸãã
æ¬èšäºã§ã¯Flutterã䜿ã£ãç°¡åãªã¢ããªã±ãŒã·ã§ã³ãäœæããFlutterã®åºæ¬çãªéçºãäœéšã»åŠç¿ããããšãç®çãšããŸãã
- ã€ã³ã¹ããŒã«
- Macã«å¿ èŠãªããŒã«ïŒFlutterã®ã€ã³ã¹ããŒã«ïŒflutter doctorïŒAndroid StudioïŒAVDã®ã»ããã¢ãã
- ãµã³ãã«ã»ã¢ããª
- ãµã³ãã«ã»ã¢ããªã®èµ·åïŒãµã³ãã«ã»ã¢ããªã®ãœãŒã¹ã³ãŒã
- ããããªããŒã
- èªåããããªããŒãã®èšå®ïŒããžãã¯ã®ããããªããŒãïŒè§£èª¬: setStateã«ã€ããŠ
- æ°ããªã¢ããªãäœã
- ã¢ããªãäœãæºåïŒHTTPéä¿¡ïŒAndroidManifest.xmlïŒJSONã®ããŒã¹ïŒç»åã衚瀺ãã
- ãªãªãŒã¹ãã«ã
- ã€ã³ã¹ããŒã«ïŒãªãªãŒã¹
ã€ã³ã¹ããŒã«
ãŸãã¯Flutterãã€ã³ã¹ããŒã«ããŸããããWindowsãMacãLinuxãChromeOSã§äœ¿çšã§ããŸãã
Flutterã®å ¬åŒãµã€ãå³äžã«ãããGet startedãã®ãã¿ã³ãããå ¬åŒã¬ã€ãã§ã®ã€ã³ã¹ããŒã«ã®æé ãåç §ã§ããŸããå ¬åŒã¬ã€ãã詳现ãã€ææ°æ å ±ã§ã¯ãããŸãããæ¬èšäºã§ãMacç°å¢ã§Android Studioã䜿ãå Žåã®ã€ã³ã¹ããŒã«ã»ã»ããã¢ããã®æé ã«ã€ããŠè§£èª¬ããŸããä»ã®OSãIDE/ãšãã£ã¿ã«ã€ããŠã¯å ¬åŒã¬ã€ããåç §ããŠãã ããã
Macã«å¿ èŠãªããŒã«
Flutterã¯ä»¥äžã®ã³ãã³ãã©ã€ã³ããŒã«ãå©çšããŸãã
- bash
- curl
- git 2.x
- mkdir
- rm
- unzip
- which
â»ãããã¯Macã®ç°å¢ã«æšæºã§å ¥ã£ãŠããŸããè¶³ããªããã®ãããã°å¥éã€ã³ã¹ããŒã«ããŠãã ããã
Flutterã®ã€ã³ã¹ããŒã«
macOSçšããŠã³ããŒãããŒãž ã®ãflutter_macos_v1.7.8+hotfix.3-stable.zipãã®ãã¿ã³ãããzipãã¡ã€ã«ãããŠã³ããŒãããŠãã ããïŒããŒãžã§ã³ã®è¡šèšã¯æ¬èšäºã®å·çæç¹ã®ãã®ã§ãïŒã
ããŠã³ããŒãããzipãã¡ã€ã«ããã€ã³ã¹ããŒã«ãããå Žæã«å±éããŸãã以éãæäœã¯ã¿ãŒããã«ã§è¡ããã®ãšããŠãã³ãã³ãäŸã瀺ããŸãã ~/development ã«ã€ã³ã¹ããŒã«ãããå Žåã¯ä»¥äžã®ããã«ãªããŸãã
mkdir ~/development cd ~/development unzip ~/Downloads/flutter_macos_v1.7.8+hotfix.3-stable.zip
~/development/flutter ãšãããã£ã¬ã¯ããªãäœæããããã®äžã«Flutterã®ãã¡ã€ã«ãå±éãããŸãã
Flutterã®ã³ãã³ããç°¡åã«å©çšã§ããããã«ããããã«ãç°å¢å€æ° PATH ã«Flutterã€ã³ã¹ããŒã«å
ãèšå®ããŠãããŸãããã
~/.bash_profile ã«ä»¥äžã®è¡ã远å ããŸãã [YOUR_NAME] ã¯ãèªèº«ã®ãŠãŒã¶ãŒåã«çœ®ãæããŠãã ããããŸããã€ã³ã¹ããŒã«å
ãå¥ã®å Žæã«ããå Žåããé©å®ãã¹ã眮ãæããŠãã ããã
export PATH="$PATH:/Users/[YOUR_NAME]/development/flutter/bin"
sourceã³ãã³ãã§ãçŸåšã®ã»ãã·ã§ã³ã«ãåæ ãããŸãã
source ~/.bash_profile
flutter doctor
Flutterã«ã¯ç°å¢ããã§ãã¯ãã doctor ãšããã³ãã³ãããããŸãããã®ã³ãã³ããå®è¡ããããšã§ãFlutterãå¿
èŠãšããDart SDKãªã©ãããŠã³ããŒãã»ã»ããã¢ãããããŸãã以äžã®ããã«å®è¡ããŠãã ããã
flutter doctor
â»flutterã³ãã³ããèŠã€ãããªãå Žåã¯ãåç« ã§ã® flutter/bin ã«ãã¹ãéãèšå®ãèŠçŽããŠãã ããã
以äžã®ããã«é¢é£ããããŒã«ã®ç¶æ³ã衚瀺ãããç°å¢ãæŽã£ãŠããé
ç®ã¯ã â ãã§è¡šç€ºãããŸãããªãç®æã«ã€ããŠã¯ã ! ããšè¡šç€ºãããŸããããã§ã¯å°ãªããšãå
é ã®Flutterã®æ¬ãã â ããšãªã£ãŠããã°OKã§ãã
Doctor summary (to see all details, run flutter doctor -v): [â] Flutter (Channel stable, v1.7.8+hotfix.3, on Mac OS X 10.14.4 18E226, locale ja-JP) [â] Android toolchain - develop for Android devices (Android SDK version 28.0.3) [â] Xcode - develop for iOS and macOS (Xcode 10.2) [â] iOS tools - develop for iOS devices [â] Android Studio (version 3.3) [â] IntelliJ IDEA Ultimate Edition (version 2018.1) [â] VS Code (version 1.35.1) [â] Connected device (2 available)
ãã®åŸã®Android Studioãã»ããã¢ããåŸã«ã¯ãäžèšã®æ¬ã®ãã¡Android toolchainãAndroid Studioã®æ¬ãã âããšãªããéçºãé²ããããããã«ãªããŸãããªããiOSã§Flutterã¢ããªãéçºãããå Žåã¯ãå¥éXcodeã®ã€ã³ã¹ããŒã«ãå¿
èŠã§ãã
Android Studio
Flutterã«ã¯Android StudioãIntelliJ IDEAãVisual Studio Codeåãã®å ¬åŒãªéçºãã©ã°ã€ã³ããããŸãããŸãããã©ã°ã€ã³ãå©çšãããšããFlutterã®ã³ãã³ãã©ã€ã³ããŒã«ã䜿ãããããã奜ããªãšãã£ã¿ã§Flutterã§ã¢ããªéçºãã§ããŸãã
æ¬èšäºã§ã¯Android Studioã䜿ãå Žåã®æé ã玹ä»ããŸãã
Android Studioã®ã€ã³ã¹ããŒã«
ãŸããAndroid Studioã®å ¬åŒãµã€ããããAndroid StudioãããŠã³ããŒãããŸãã
Android Studioãèµ·åããAndroid Studio Setup Wizardãé²ããŸããããã«ããAndroid SDKãAndroid SDK Platform-ToolsãAndroid SDK Build-Toolsãšãã£ããFlutterã«å¿ èŠãªåããŒã«ãã€ã³ã¹ããŒã«ãããŸãã
æ¬èšäºã§ã¯ãšãã¥ã¬ãŒã¿ã䜿ã£ãŠéçºããŠãããŸããã宿©ããã€ã¹ã䜿ã£ãéçºã«ãããŠãåºæ¬çãªæé ã«éãã¯ãããŸããã
â»Android Studioããã§ã«ã€ã³ã¹ããŒã«æžã¿ã®å Žåã¯ãããŒãžã§ã³ã3.1以äžã§ããããšã確èªããŠãã ããã
â»æ¬èšäºã®å·çæç¹ã§ã®Android Studioã®ææ°ããŒãžã§ã³ã¯3.4.2ã§ãããç»é¢ã®ã¹ã¯ãªãŒã³ã·ã§ãããªã©ã¯3.3ã§æ®åœ±ããŠããŸãã
Flutterãã©ã°ã€ã³ã®ã€ã³ã¹ããŒã«
Android Studioåãã®Flutterãã©ã°ã€ã³ãã€ã³ã¹ããŒã«ããŠäœ¿ããŸããAndroid Studioã®PreferencesããPluginsãéžæããç»é¢äžéšã®Browse repositoriesãéžãã§ãã ããã
ãflutterãã§ç»é¢å ãæ€çŽ¢ããŠè¡šç€ºããããFlutterããéžã³ãInstallãã¿ã³ã§ã€ã³ã¹ããŒã«ããŸãã
ã€ã³ã¹ããŒã«åŸãAndroid Studioãåèµ·åããŠãã ãããåèµ·ååŸãAndroid Studioã®éå§ç»é¢ã«ãStart a new Flutter projectãã®ã¡ãã¥ãŒã衚瀺ãããããã«ãªãã®ã§ããããéžæããŸãã
New Flutter Projectã®ç»é¢ã§ã¯ãFlutter Applicationããéžã³ãNextããžé²ã¿ãŸãã
Project nameã«ã¯ã奜ããªååãå ¥ããŠãã ãããFlutter SDK pathã«ã¯ãã€ã³ã¹ããŒã«ããFlutterã®ãã¹ãå ¥ã£ãŠããŸããProject locationã«ã¯ããã®ã¢ããªãäœæããå Žæãå ¥åããŸãã
Company domainã¯ãã¢ããªã®ãªãªãŒã¹æã«Androidã¢ããªã®ããã±ãŒãžåïŒiOSã®å Žåã¯ãã³ãã«IDïŒãšããŠäœ¿ãããŸããæ¬èšäºã¯ãã¥ãŒããªã¢ã«ã®ããã example.com ã®ãŸãŸé²ããŠãããŸãã
ããŠãã¢ããªã®é圢ãäœæããããšãAndroid Studioã®ãšãã£ã¿ãèµ·åããŠä»¥äžã®ãããªç¶æ ãšãªããŸãã
AVDã®ã»ããã¢ãã
ã¢ããªãAndroidãšãã¥ã¬ãŒã¿ã§å®è¡ããããã«ã¯ãAVDïŒAndroid Virtual DeviceïŒã®èšå®ãå¿ èŠã§ãã
Android Studioã®ToolsãããAVD ManagerããéžæããAVDã®äžèЧç»é¢ã衚瀺ãããããå·Šäžã®ãïŒCreate Virtual Deviceããéžã³ãŸããæ¬¡ã®ç»é¢ã§ã¯ä»»æã®Hardwareãéžãã§ãNextããžé²ã¿ãŸãã
次ã«ãSystem imageãéžã³ãŸããRecommendedã®ã¿ãã«è¡šç€ºãããŠããäžããéžã¹ã°OKã§ããçŸè¡ã®Macã®CPUã¯Intelãæ¡çšããŠãããABIïŒApplication Binary InterfaceïŒãx86ãx86_64ã®ãã®ã§ãåé¡ãªãé«éã«åäœããã§ããããæ¬çš¿ã§ããx86ãx86_64ãæšå¥šããŸããããŠã³ããŒããå¿ èŠãªãã®ã«ã¯ãDownloadãã®ãªã³ã¯ã衚瀺ãããŠããã®ã§ãå¿ èŠã«å¿ããŠããŠã³ããŒãããŠãã ããã
Emulated Performanceã®é ç®ã§ãHardware - GLES 2.0ããéžæããŠãã ããã
äœæãå®äºããããç»é¢å³ã®åçãã¿ã³ã§ãšãã¥ã¬ãŒã¿ãèµ·åããŸãã
ãããŸã§æ¥ãããFlutterã¢ããªãAndroidãšãã¥ã¬ãŒã¿ã§å®è¡ããæºåã¯å®äºã§ãã
ãµã³ãã«ã»ã¢ããª
ãµã³ãã«ã»ã¢ããªã®èµ·å
Android Studioã®ãStart a new Flutter projectãã«ãã£ãŠFlutterã®ãµã³ãã«ã»ã¢ããªãé圢ãšããŠäœæãããŠããããããŸãã¯ãã®ã¢ããªãèµ·åããŠã¿ãŸãããã
Android Studioã®äžéšã«Flutterãã©ã°ã€ã³ã®ããŒã«ããŒããããŸãããAndroid SDK build for x86ããšè¡šç€ºãããŠããã®ããAndroidãšãã¥ã¬ãŒã¿ã§ããä»ã«å®æ©ããã€ã¹ã®æ¥ç¶ãããã°ããã«ããŠã³ããéžæã§ããŸããã¢ããªãå®è¡ãããç°å¢ãéžãã§ãã ããã
ãmain.dartããšããã®ãã¢ããªã®ãšã³ããªãã€ã³ãã§ãããã®æç¹ã§ã¯ä»ã«ãã¡ã€ã«ããªãããããã®ãŸãŸã§OKã§ãããã®å³ã«ããåçãã¿ã³ãæŒããŠã¢ããªãèµ·åããŸãããã
â»Androidã®å®æ©ããã€ã¹ã§éçºãããå Žåã¯ã端æ«ã®éçºè ãªãã·ã§ã³ã®ãUSBãããã°ããæå¹ã«ããŠãã ããããŸããWindowsã§Androidããã€ã¹ã䜿ãå Žåã¯ãUSBãã©ã€ããå¿ èŠã§ãã詳ããã¯ãŠãŒã¶ãŒã¬ã€ãã®ãGoogle USB ãã©ã€ããå ¥æããããåç §ããŠãã ããã
èµ·åãããšä»¥äžã®ããã«ãªããŸãããªãããµã³ãã«ã»ã¢ããªã®ååèµ·åæã¯Androidã¢ããªã®éåžžã®ã³ã³ãã€ã«ãè¡ããããããæ°åç§ããæ°åãæéããããããšããããŸãã
ç»é¢å·Šã«é 眮ãããŠãããµã³ãã«ã»ã¢ããªç»é¢ã®å³äžã®ãïŒããã¿ã³ãæŒããšãã¢ããªç»é¢äžå€®ã«è¡šç€ºãããŠããæ°åãã«ãŠã³ãã¢ããããŸãã
ãµã³ãã«ã»ã¢ããªã®ãœãŒã¹ã³ãŒã
ãµã³ãã«ãšããŠäœæããããã®ã¢ããªã¯ã以äžã®ã³ãŒãã«ãªã£ãŠããŸãïŒã³ã¡ã³ãéšåãé€ãïŒã
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
ããã60è¡ã»ã©ã®ã³ãŒãã§ãã¢ããªã±ãŒã·ã§ã³ãšããŠåäœãããã®ãåºæ¥äžãã£ãŠããŸãã
æ¬èšäºã§ã¯Flutterãã¬ãŒã ã¯ãŒã¯ã®è©³çްã«ã€ããŠã¯è§ŠããŸãããããã®ã³ãŒãã«ç»å ŽããèŠçŽ ã«ã€ããŠãç°¡åã«è¿°ã¹ãŠãããŸã:
-
main颿°ããåŠçãéå§ãããrunAppã«Widgetãæž¡ãããšã§ã¢ããªã衚瀺ããã -
MyAppã¯StatelessWidgetãç¶æ¿ããŠãããWidgetã§ãã -
MyHomePageã¯StatefulWidgetãç¶æ¿ããŠãããç¶æ ãããããšãæå³ããïŒ_MyHomePageStateããã®ç¶æ ïŒ -
WidgetãStateã®buildã¡ãœããã®æ»ãå€ããç»é¢ã«è¡šç€ºãããUIãšãªã -
MaterialAppã¯ãããªã¢ã«ãã¶ã€ã³ã®ã¢ããªãäœãããã«äŸ¿å©ãªWidget -
Scaffoldã¯å žåçãªç»é¢ã¬ã€ã¢ãŠããæ§ç¯ãã䟿å©ãªWidget
ããããªããŒã
ã§ã¯ãFlutterã®ç¹é·ã®ã²ãšã€ã§ãããããããªããŒãã詊ããŠã¿ãŸãããã
ã¢ããªã¯èµ·åãããŸãŸãã³ãŒãå ã®æåå
'You have pushed the button this many times:'
ã®äžèº«ãã
'ãã¿ã³ããã®åæ°ãæŒããŸãã'
ã«å€æŽããŠãã ããã
ãã¡ã€ã«ã®å€æŽãä¿åãããšãã¢ããªå ã®æååãå³åº§ã«å€æŽãããŸãã
ããã¯ãFlutterãã©ã°ã€ã³ã§ãã¡ã€ã«ä¿åããéã®èªåããããªããŒãããããã©ã«ãã§æå¹ã«ãªã£ãŠããããã§ãã
èªåããããªããŒãã®èšå®
Android Studioã®PreferenceãããLanguages & Frameworksã > ãFlutterããéžã¶ãšãFlutterã«é¢ãããªãã·ã§ã³ã倿Žã§ããŸããèªåããããªããŒãããªãã«ãããå Žåã¯ãPerform hot reload on saveãã®ãã§ãã¯ãå€ããŸãã
èªåããããªããŒãããªãã®ç¶æ ã§ããããªããŒãããå Žåã¯ãããŒã«ããŒã«ãã皲劻ã®åœ¢ã®ãã¿ã³ãæŒããŸãã
ããžãã¯ã®ããããªããŒã
ããããªããŒãã§ããã®ã¯æååãšãã£ã宿°ã ãã§ã¯ãããŸããããã¿ã³ãæŒãããšãã®åŠçãè¡ã£ãŠãã _incrementCounter ã¡ãœããã®äžèº«ãã2ãã€è¶³ããŠãããããã«æžãæããŠã¿ãŸããããã³ãŒãã¯ä»¥äžã®éãã§ãã
void _incrementCounter() { setState(() { _counter += 2; }); }
ããããªããŒãããŠããïŒããã¿ã³ãæŒããŠã¿ãŠãã ãããæ°åã2ãã€å¢ããããã«ãªããŸããã
解説: setStateã«ã€ããŠ
_counter ã®æŽæ°ã¯ãsetState ãšããã¡ãœããã«æž¡ããç¡å颿°å
ã§ä»£å
¥ïŒïŒç¶æ
ã®å€æŽïŒãè¡ã£ãŠããŸãã
ãã® setState ã¡ãœããã®åŒã³åºãã«ãã£ãŠãFlutterãã¬ãŒã ã¯ãŒã¯ã«å¯ŸããŠãç¶æ
ãå€ãã£ããããšãäŒãããŸããFlutterãã¬ãŒã ã¯ãŒã¯ã¯ããã®ããšã§ build ã¡ãœãããåŒã³åºãããšã§ç»é¢ãææ°ã®ç¶æ
ã«æŽæ°ããŸãã
æ°ããªã¢ããªãäœã
ãµã³ãã«ã»ã¢ããªã¯ãããŸã§ã«ããŠãããå®è·µçãªã¢ããªãäœããŸãããã
äžã®äžã®å€ãã®ã¢ããªã«ãããHTTPéä¿¡ãè¡ããããªã¹ããã¥ãŒã«ãã£ãŠå€æ°ã®é ç®ã衚瀺ããããšãã£ãæ©èœãå®è£ ããŸããæ¬èšäºã§ã¯GitHubã®Flutterãªããžããªã«ããIssuesãäžèŠ§è¡šç€ºããã¢ããªãäœã£ãŠãããŸãã
ã¢ããªãäœãæºå
ãŸã㯠MyApp ã¯ã©ã¹ã® title ã®æååã Flutter Issues ã«å€æŽãã _MyHomePageState ã¯ã©ã¹ã® build ã¡ãœããå
ã以äžã®ããã«ç©ºã£ãœã«è¿ãç¶æ
ã«ããŠãæ°ããªã¢ããªã«åããŸãã
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Issues', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Issues'), ); } }
class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Text('空ã£ãœã®ç»é¢ã§ã'), ); } }
ã¹ã¯ãªãŒã³ã·ã§ãã
pubspec.yaml
Flutterã§ã¯ãå€éšããã±ãŒãžãªã©ã®äŸåé¢ä¿ãã¢ããªã®èšå®ã¯pubspec.yamlãšãããã¡ã€ã«ã«èšè¿°ããŸãããã¡ã€ã«ã¯é圢ãšãšãã«äœæãããŠããŸãã
ã¢ããªã®é圢ãäœæããæç¹ã§ã¯ãpubspec.yamlã¯ä»¥äžã®ããã«ãªã£ãŠããŸãïŒã³ã¡ã³ãéšåã¯é€ãïŒã
name: flutter_app description: A new Flutter application. version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.2 dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true
dependencies
ãã®ãã¡ã€ã«ã® dependencies ã®é
ç®ã«ã http ã远å ããŸãã
dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.2 http: any
packages get
httpããã±ãŒãžã®èšè¿°ã远å ããåŸã¯ããšãã£ã¿ç»é¢äžéšã«è¡šç€ºãããFlutter commandsã®ãPackages getããéžãã§å®è¡ããŠãã ãããããã«ãããpubspec.yamlã«èšèŒãããå€éšããã±ãŒãžãªã©ãååŸããã䜿ããããã«ãªããŸãã
ãšãã£ã¿äžéšã®ã³ã³ãœãŒã«ã«ä»¥äžã®ããã«è¡šç€ºãããã°åŠçã¯æåã§ãã
Tips: pub
FlutterãDartã®åçš®ããã±ãŒãžã¯ããDart packagesãã§æ¢ããŸãã
import
ã³ãŒãã§httpããã±ãŒãžãå©çšããããã«ã¯ import ãå¿
èŠã§ãã以äžã®ããã«importæã远å ããŠãã ããã
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http;
as http ãšããã®ã¯ã import ããããã±ãŒãžå
ã®ååã«ãã¬ãã£ãã¯ã¹ãã€ããŠå©çšããããã§ããhttpããã±ãŒãžã«ã¯getãpostãšãã£ãåçŽãªååããããä»ã®èå¥åãšã®è¡çªãé¿ãããå Žåãªã©ã«ãã®æ©èœã䜿ããŸãã
HTTPéä¿¡
HTTPéä¿¡ã«ãã£ãŠãå€éšããããŒã¿ãèªã¿èŸŒãã§ã¿ãŸãã
Flutterãªããžããªã®Issuesã®äžèЧãååŸããAPIã®ãšã³ããã€ã³ãã«ã¢ã¯ã»ã¹ããŠãããŒã¿ãååŸããŸãããã®URLããã©ãŠã¶ã§è¡šç€ºãããšAPIã®äžèº«ã確èªã§ããŸãã
ãœãŒã¹ã³ãŒã
_MyHomePageState ã以äžã®ããã«ããŸãã倿ŽåŸãFlutterããŒã«ããŒã®åçãã¿ã³ãæŒããŠããããªã¹ã¿ãŒããè¡ã£ãŠãã ãããããããªããŒãã§ã¯è¡šç€ºãæŽæ°ãããŸããã
class _MyHomePageState extends State<MyHomePage> { String _data = ''; @override void initState() { super.initState(); _load(); } Future<void> _load() async { final res = await http.get('https://api.github.com/repositories/31792824/issues'); setState(() { _data = res.body; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Text(_data), ); } }
ã¹ã¯ãªãŒã³ã·ã§ãã
ããããªã¹ã¿ãŒãåŸã以äžã®ããã«ãGitHubã®APIããååŸããFlutterãªããžããªã®Issues APIã®äžèº«ãããã®ãŸãŸæååãšããŠè¡šç€ºãããŸãã
ããããªã¹ã¿ãŒã
Flutterã®ããããªããŒããè¡ããšã build ã¡ãœãããåŒã³åºãããŠç»é¢ãæŽæ°ãããŸããä»åã®ã³ãŒãã®å€æŽã§ã¯æ°ãã«httpããã±ãŒãžã远å ããããã« initState ã¡ãœããã§åæååŠçãè¡ãããã«ããŸãããã衚瀺ãããŠããWidgetïŒStateïŒã® initState ã¯ããããªããŒãã§ã¯ååŒã³åºããããŸããããã®ãããããããªã¹ã¿ãŒãã§ã¢ããªãæåããå®è¡ãããããšã§ initState ïŒãšããããåŒã³åºããã _load ã¡ãœããïŒãå®è¡ãããHTTPéä¿¡ã®çµæãç»é¢ã«è¡šç€ºããããã«ããŸããã
Flutterã¢ããªãéçºäžã«ãæå³ããéãã«æŽæ°ãè¡ãããªãã£ãå Žåã¯ããã® initState ãååŒã³åºããããªãã£ãããšãåå ã®å¯èœæ§ããããŸãããã®éã¯ããããªã¹ã¿ãŒãã詊ããŠã¿ãŠãã ããã
解説
ããã§ã®å€æŽã®ãã€ã³ãã¯ä»¥äžã®éãã§ãã
class _MyHomePageState extends State<MyHomePage> { String _data = '';
- ååŸããããŒã¿ãä¿æããã€ã³ã¹ã¿ã³ã¹å€æ°
_dataã远å ããŸãã
@override void initState() { super.initState(); _load(); }
-
initStateã¡ãœãããoverrideããŸã ãinitStateã¯ããã®ãªããžã§ã¯ããç»é¢ïŒWidget treeïŒã«è¿œå ãããæã«åŒã³åºãããåæååŠçãªã©ãèšè¿°ã§ããŸããããã§ã¯å¥éå®è£ ãã_loadã¡ãœãããåŒã³åºããŠãHTTPéä¿¡ãéå§ãããŠããŸãã
Future<void> _load() async { final res = await http.get('https://api.github.com/repositories/31792824/issues'); setState(() { _data = res.body; }); }
-
_loadã¡ãœããã¯asyncããŒã¯ãŒãã«ãããéåæã¡ãœããã«ãªã£ãŠããŸããhttp.getïŒhttpããã±ãŒãžã®get颿°ïŒã¯éåæã§HTTPéä¿¡ãè¡ãFutureãè¿ããŸãããã®çµæãawaitã§åŸ ã¡åããŠããŸãã - æ»ãå€ãåãåã倿°
resã¯finalã§å®£èšããŠããããã以éã¯åä»£å ¥ã§ããŸããããŸãååã®å®£èšã¯çç¥ããŠããŸãïŒDartãæšè«ã§åã解決ããŠããŸãïŒã - HTTPéä¿¡ã®ã¬ã¹ãã³ã¹ã®äžèº«ïŒ
res.bodyïŒãã€ã³ã¹ã¿ã³ã¹å€æ°_dataã«ä»£å ¥ããŠããŸããsetStateã«ãã£ãŠç¶æ ãå€ãã£ãããšãFlutterã«äŒããŸãã -
bodyã®Text widgetã¯ã€ã³ã¹ã¿ã³ã¹å€æ°_dataã®äžèº«ã衚瀺ããŸãã
ãªããasync/awaitã䜿ããã« _load ã¡ãœãããèšè¿°ãããšä»¥äžã®ããã«ãªããŸãã http.get ãè¿ãFutureãªããžã§ã¯ãã«å¯Ÿã㊠then ã¡ãœããã§ã³ãŒã«ããã¯é¢æ°ãæž¡ããŸããåŠçãå®äºãããšãã®ã³ãŒã«ããã¯é¢æ°ãåŒã³åºãããŸãããã®æ¹æ³ã¯async/awaitããµããŒãããã以åã®æ¹æ³ã§ãããçŸæç¹ã§ã¯async/awaitãäœ¿ãæ¹æ³ãæšå¥šãããŠããŸãã
void _load() { http.get('https://api.github.com/repositories/31792824/issues').then((http.Response res) { setState(() { _data = res.body; }); }); }
Tips: _ã§å§ãŸãåå
Dartã§ã¯ã _ ã§å§ãŸãèå¥åã¯ãä»ã®ãã¡ã€ã«ããã¢ã¯ã»ã¹ããããšãã§ããŸããããã®ãããå€éšã«å
¬éããå¿
èŠã®ãªã倿°ãã¡ãœããã _ ããå§ãŸãååã«ããŠããŸãã
AndroidManifest.xml
ããã§ãAndroidã®ããŒããã·ã§ã³ã®èšå®ãããŠãããŸãããã
ãããã°ãã«ãã§ã¯ããŒããã·ã§ã³ã«ãããšã©ãŒã¯çºçããŸãããããªãªãŒã¹ãã«ãããæã«æš©éããªããšHTTPéä¿¡ã倱æããŸãã android/app/src/main/AndroidManifest.xml ã«ã以äžã®ããã« uses-permission ã远èšããŠãã ããã
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.flutter_app"> <uses-permission android:name="android.permission.INTERNET" />
JSONã®ããŒã¹
GitHubã®APIã¯JSON圢åŒã§ããDartã«ã¯æšæºããã±ãŒãžã§JSONã®åŠçãè¡ã颿°ãçšæãããŠããããããå©çšããŠããŒã¹ãè¡ããŸãã
import
Dartã® convert ããã±ãŒãžã import ããŠãã ããã
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http;
ããã§ã以äžã®ããã«äœ¿ãããšãã§ããŸãã
final data = json.decode(res.body);
ãœãŒã¹ã³ãŒã
GitHub Issuesã®ã¿ã€ãã«ã List ã§æ±ãããªã¹ã圢åŒã§è¡šç€ºãããã _MyHomePageState ãæŽæ°ããŸããä»åã initState ã§åŒã³åºãããåŠçãå€ãã£ãŠããã®ã§ãããããªã¹ã¿ãŒãã§æŽæ°ããŠãã ããã
class _MyHomePageState extends State<MyHomePage> { List<String> _titles = <String>[]; @override void initState() { super.initState(); _load(); } Future<void> _load() async { final res = await http.get('https://api.github.com/repositories/31792824/issues'); final data = json.decode(res.body); setState(() { final issues = data as List; issues.forEach((dynamic element) { final issue = element as Map; _titles.add(issue['title'] as String); }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: ListView.builder( itemBuilder: (BuildContext context, int index) { if (index >= _titles.length) { return null; } return ListTile( title: Text(_titles[index]), ); }, ), ); } }
ã¹ã¯ãªãŒã³ã·ã§ãã
衚瀺ããããªã¹ããã¹ã¯ããŒã«ããŠã¿ãŠãã ãããã¹ã¯ããŒã«ã端ã«å°éããéãªã©ããã€ãã£ãã¢ããªãšå€ãããªãæåã«ãªã£ãŠããããšãåãããšæããŸãã
ãªããiOSã§å®è¡ããå Žåã¯ç«¯ã§ããŠã³ã¹ããAndroidã¯çµç«¯ã®ãšãã§ã¯ãã衚瀺ãããŸããããã¯Flutterã®å éšã§ãã¹ã¯ããŒã«ã®æåãOSã«å¿ãããã®ã«ãªãããã«å®è£ ããŠããããã§ãã
解説
class _MyHomePageState extends State<MyHomePage> { List<String> _titles = <String>[];
- ã€ã³ã¹ã¿ã³ã¹å€æ°ã
List<String>ã«å€æŽããè€æ°ã®Issuesã®ã¿ã€ãã«ãæ±ããããã«ããŠããŸãã
Future<void> _load() async { final res = await http.get('https://api.github.com/repositories/31792824/issues'); final data = json.decode(res.body); setState(() { final issues = data as List; issues.forEach((dynamic element) { final issue = element as Map; _titles.add(issue['title'] as String); }); }); }
-
json.decodeããçµæããIssuesã®ã¿ã€ãã«ãåãåºããŠããŸããAPIå šäœã¯ListãåèŠçŽ ã¯Mapããã®äžã®titleãã¿ã€ãã«ã§ããjson.decodeã®æ»ãå€ã¯åãdynamicãšå®ãŸã£ãŠããªãïŒJSONã®åœ¢åŒã¯äžå®ãªããïŒã®ã§ãasããŒã¯ãŒãã«ãã£ãŠListãMapã«ãã£ã¹ãããŠããŸãã
body: ListView.builder( itemBuilder: (BuildContext context, int index) { if (index >= _titles.length) { return null; } return ListTile( title: Text(_titles[index]), ); }, ),
- ãªã¹ãã®è¡šç€ºã«ã¯
ListViewãšããWidgetã䜿ããŸããListView.builderã¯ãListViewã®ã¯ã©ã¹ã®ååä»ãã³ã³ã¹ãã©ã¯ã¿ã§ãã -
itemBuilderã«ãªã¹ãã®åèŠçŽ ããã«ãããããã®é¢æ°ãæž¡ããŠããŸããListViewã¯ã©ã¹ãèŠçŽ ã®äœçœ®ãindexãšããŠæž¡ããåŒã³åºããŠããã®ã§ããã®äœçœ®ã«å¿ããWidgetãè¿ããŸããnullãè¿ããšãªã¹ãã¯çµç«¯ãšãªãã®ã§ã_titlesã®ä»¶æ°ãè¶ ãããšããã§nullãè¿ããŠããŸãã -
ListTileã¯ãå žåçãªãªã¹ãèŠçŽ ã®ã¬ã€ã¢ãŠããå®çŸããŠãããWidgetã§ãããã®titleã«Text widgetãèšå®ããŠããŸããListTileã ãã§ãªããä»»æã®WidgetãèŠçŽ ã«äœ¿ãããšãã§ããŸãã
ç»åã衚瀺ãã
ã¿ã€ãã«ã ãã§ã¯å¯ããã®ã§ãIssueãç»é²ãã人ã®ã¢ãã¿ãŒç»åãäžç·ã«è¡šç€ºããŸãããã
ãœãŒã¹ã³ãŒã
GitHub Issuesã®ã¿ã€ãã«ãšãŠãŒã¶ãŒã®ã¢ãã¿ãŒç»åã List ã§æ±ããããã _MyHomePageState ãæŽæ°ããŸããä»åã initState ã§åŒã³åºãããåŠçãå€ãã£ãŠããã®ã§ãããããªã¹ã¿ãŒãã§æŽæ°ããŠãã ããã
class Issue { Issue({ this.title, this.avatarUrl, }); final String title; final String avatarUrl; } class _MyHomePageState extends State<MyHomePage> { List<Issue> _issues = <Issue>[]; @override void initState() { super.initState(); _load(); } Future<void> _load() async { final res = await http.get('https://api.github.com/repositories/31792824/issues'); final data = json.decode(res.body); setState(() { final issues = data as List; issues.forEach((dynamic element) { final issue = element as Map; _issues.add(Issue( title: issue['title'] as String, avatarUrl: issue['user']['avatar_url'] as String, )); }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: ListView.builder( itemBuilder: (BuildContext context, int index) { if (index >= _issues.length) { return null; } final issue = _issues[index]; return ListTile( leading: ClipOval( child: Image.network(issue.avatarUrl), ), title: Text(issue.title), ); }, ), ); } }
ã¹ã¯ãªãŒã³ã·ã§ãã
解説
class Issue { Issue({ this.title, this.avatarUrl, }); final String title; final String avatarUrl; }
- Issueããšã®ããŒã¿ã衚ã
Issueã¯ã©ã¹ãå®çŸ©ããŸããã
class _MyHomePageState extends State<MyHomePage> { List<Issue> _issues = <Issue>[];
- ã€ã³ã¹ã¿ã³ã¹å€æ°ã
List<Issue>ã«å€æŽããŠãIssueãªããžã§ã¯ãã®ãªã¹ããšããŠããŸãã
Future<void> _load() async { final res = await http.get('https://api.github.com/repositories/31792824/issues'); final data = json.decode(res.body); setState(() { final issues = data as List; issues.forEach((dynamic element) { final issue = element as Map; _issues.add(Issue( title: issue['title'] as String, avatarUrl: issue['user']['avatar_url'] as String, )); }); }); }
- APIã¬ã¹ãã³ã¹ãããŒã¹ããçµæãªã¹ãã®åèŠçŽ ãã
Issueã¯ã©ã¹ã®ãªããžã§ã¯ããçæããŠãã_issuesã«addããŠããŸãã
body: ListView.builder( itemBuilder: (BuildContext context, int index) { if (index >= _issues.length) { return null; } final issue = _issues[index]; return ListTile( leading: ClipOval( child: Image.network(issue.avatarUrl), ), title: Text(issue.title), ); }, ),
-
ListTileã®leadingã«ãŠãŒã¶ãŒã®ã¢ãã¿ãŒç»åã远å ããŸããã -
Image.networkã§ããããã¯ãŒã¯äžã®ç»åã衚瀺ããImage widgetã®ãªããžã§ã¯ããçæããŠããŸãã -
ClipOvalã¯childãå圢ã«ã¯ãªããããŠè¡šç€ºããwidgetã§ãããã«ããç»åãäžžãåãåã£ãŠè¡šç€ºããŠããŸãã
ãªãªãŒã¹ãã«ã
ããŠãæ¬èšäºã§ã®ã¢ããªã¯ããã§å®æã§ãã
ã€ã³ã¹ããŒã«
宿©ã®Androidããã€ã¹ããæã¡ã®æ¹ã¯ããªãªãŒã¹ãã«ããã.apkãã¡ã€ã«ãã宿©ã«ã€ã³ã¹ããŒã«ããŠã¿ãŸãããã flutter install ãšããã³ãã³ããçšæãããŠããŸãã
ãŸãã¯ã宿©ããã€ã¹ãUSBã±ãŒãã«ã§ãã·ã³ã«æ¥ç¶ãã flutter devices ã³ãã³ãã䜿ã£ãŠã¿ãŸãã
flutter devices
以äžã®ããã«æ¥ç¶ãããããã€ã¹ã衚瀺ãããŸãã以äžã®äŸã§ããã°å®æ©ã®ããã€ã¹IDã¯ãLPF0000000000000ãã§ãã
HW 01K ⢠LPF0000000000000 ⢠android-arm64 ⢠Android 8.1.0 (API 27) Android SDK built for x86 ⢠emulator-5554 ⢠android-x86 ⢠Android 8.1.0 (API 27) (emulator) macOS ⢠macOS ⢠darwin-x64 ⢠Mac OS X 10.14.4 18E226 web ⢠web ⢠web-javascript ⢠Google Chrome 75.0.3770.142
ãã®ããã€ã¹IDã install ã³ãã³ãã§ä»¥äžã®ããã«æå®ããŸããããã€ã¹IDã¯ããèªèº«ã®ãã®ã«çœ®ãæããŠãã ããã
flutter install -d LPF0000000000000
Initializing gradle... 5.7s Resolving dependencies... 2.1s Installing app.apk to HW 01K... Installing build/app/outputs/apk/app.apk... 2.6s
宿©ã«flutter_appãšããã¢ããªãã€ã³ã¹ããŒã«ãããŠããã¯ãã§ãã
ãªãªãŒã¹ãã«ãã§ã¯ãéçºäžã«è¡šç€ºãããŠããç»é¢å³äžã®ãDEBUGãã®åž¯ããªããªã£ãŠããŸãããŸããåäœããã軜快ã«ãªã£ãŠããããšã確èªã§ãããšæããŸãã
ãªãªãŒã¹
ãªãªãŒã¹ãã«ããããã®ãGoogle Play Storeã«å ¬éããã®ã§ããã°ã眲åãªã©ã®æºåãå¿ èŠã§ãã詳现ã¯ä»¥äžãåç §ããŠãã ããã
- Android
- iOS
ãŸãšã
AndroidãšiOSã®ã¢ããªãåäžã®ã³ãŒãããŒã¹ã§éçºã§ããFlutterã«ã€ããŠãå®éã®ã¢ããªãäŸã«ãŸãšããŸããããã®èšäºãFlutterãçè§£ããããã®ã¬ã€ãã«ãªãã°ãšæããŸãã
Flutteré¢é£ãªã³ã¯
- å ¬åŒãµã€ã
- GitHub
- YouTube
- Stack Overflow
- Google Codelabs




