iOS Android

Flutter開発のはじめかた 開発環境セットアップ〜Widtgetの解説

投稿日:2020年2月17日 更新日:

はじめに

Flutterとは、マルチプラットフォームで動作するUIフレームワークです。単一のソースコードからiOS/Android/Web/デスクトップ用にコンパイルすることが可能です。様々な「ウィジェット」と呼ばれるUIパーツが初めから用意されており、それを組み合わせることで、簡単に美しいUIを実装することができます。
プログラミング言語には「Dart」を使用します。Dartは、元々JavaScriptを置き換える目的で開発された言語ですが、今ではFlutterで使用できることで有名です。今回は、Dartの説明はあまり深掘りしませんが、JavaScriptやJavaをやったことのある開発者であれば、すんなり理解できると思います。

セットアップ

Flutterのインストール

Flutterはこちらからインストールできます。インストール方法は各OSにより異なりますが、ここではmacOSでのインストール方法を説明します。
https://flutter.dev/docs/get-started/install

まず、Flutterのリポジトリをクローンします

次に、パスを通します。bashの場合は ~/.bash_profile、zshの場合は ~/.zshenvに記述します。

sourceコマンドでパスを読み込むか、ターミナルを再起動して、dockerのコマンドを試してみましょう。

このコマンドは開発環境をチェックし、必要なセットアップを表示してくれます。それでは、進めていきましょう。
(Dart SDKはFlutterに含まれているため、セットアップは不要です。)

Android環境のセットアップ

Android Studioに含まれているAndroid SDKを使用します。以下からAndroid Studioをインストールしてください。
https://developer.android.com/studio/?hl=ja
インストール後、Android Studioを起動し、セットアップウィザードに従い、Android SDKをインストールしてください。
(Android Studioは、後ほどIDEとして使用します。)

Xcodeのインストール

iOS ビルドにはXcodeをインストールします。(Mac AppStoreからインストールしてください。)
インストール後、コマンドラインツールの設定を行います。

ライセンスに同意し、セットアップを進めてください。

IDEのセットアップ(Android Studio)

Flutterの開発環境として、Android StudioもしくはVisual Studio Codeが推奨されています。いずれも、Flutterプラグインを導入することで、Flutterのデバッグ・ホットリロードができるようになります。
今回は、Android Studioでのセットアップ方法を紹介します。

  1. Android Studioを起動し、Preferences画面を開きます。(Welcome画面 > Configure > Preferences)
  2. Editor > Pluginsを開き、検索ボックスで flutterと検索します。
  3. Flutterプラグインの Installボタンでインストールします。
  4. 途中、Dart Pluginのインストールを尋ねるプロンプトが表示された場合は、「Yes」ボタンでインストールします。
  5. 指示に従ってAndroid Studioを再起動します。

以上で、IDEのセットアップは完了です。これで、Android Studio上でFlutter開発を一通り行う準備ができました。

Flutterプロジェクトの新規作成

  1. Android StudioのWelcome画面で「Start a new Flutter Project」を選択します。
  2. ベースとなるプロジェクトを以下の中から選択します。
    • Flutter Application
      ユーザ向けのアプリを開発する際に選択。
    • Flutter Plugin
      AndroidやiOSのネイティブAPIをFlutterから使用できるようにするプラグインを開発
    • Flutter Package
      Dartコンポーネントを作成するために使用します。例えば、自作のWidgetを、複数のプロジェクトで共有する場合に使用できます。
    • Flutter Module
      既存のAndroid/iOSアプリにFlutterコンポーネントを組み込むモジュールを開発する場合に使用します。
  3. プロジェクト設定を行います。
    Project name、Project locationを入力して進みます。Project nameはスネークケースで入力しましょう。
  4. パッケージネームの設定をします。
    Company domainは、パッケージ名に使用する企業名を指定します。Androidでのパッケージ名、iOSでのBundle Identifierで同じ値が使用されます。
    Android X、Kotlin support、Swift supportにチェックを入れます。

iOS実機ビルド

iOS実機ビルドを行うため、署名設定を行います。

  1. Flutterプロジェクト内の ios/Runner.xcworkspaceをXcodeで開きます。
  2. プロジェクト設定の “Signing & Capabilities” を開き、チーム設定等の署名設定を行います。ここは、通常のiOSアプリ開発と同じです。

この後、Android Studioで接続された実機を選択し、Runをクリックすると、実機でFlutterアプリが起動します。

Android実機ビルド

Androidの実機を接続し、iOSと同じように実機を選択し、Runすると起動します。

ホットリロード・ホットリスタート

Flutterの開発中の便利機能として、ホットリロードがあります。これは、コードをSaveすると、デバッグ中のアプリがランタイムで更新され、最新のコードが適用される機能です。
一方で、ホットリスタートは、一般的なAndroid/iOSアプリ開発と同じように、アプリをRunし直すことで、最新のコードを適用する方法です。
レイアウト変更などの、軽微な変更はホットリロードが効きますが、変更内容によってはホットリロードが効かない場合もあります。そのような場合は、ホットリスタートを行いましょう。(Android Studioであれば、 Ctrl + rでホットリスタートです)

Flutterプロジェクトの構成

Flutterプロジェクトでは、主に以下のディレクトリ・ファイルを開発に使用します。

  • lib/
    Dartコードを記載するディレクトリです。
  • test/
    Dartのテストコードを配置するディレクトリです。
  • ios/
    Xcodeプロジェクトが配置されるディレクトリです。
  • android/
    Androidプロジェクトが配置されるディレクトリです。
  • pubspec.yaml
    外部ライブラリを導入したり、アセットを登録する際に使用します。

Widgetツリー構造

Flutterでは、UIをWidgetという単位で構築し、アプリのルートから全てツリー構造となっています。
以下に、プロジェクト作成直後のWidgetツリーを図にしました。

ルートは MaterialAppWidgetとなり、 homeに渡すWidgetが、初期画面となります。ここでは、 MyHomePageを設定し、さらにその下に画面に表示するUIがツリーとなっています。

MyHomePage直下のScaffoldは、1画面を構成する土台です。 AppBar,Body,FloatingActionButtonなどの枠にWidgetを当てはめることで、簡単にアプリのUIを構築できます。大抵の場合は、 Scaffoldを使用することをお勧めします。

1画面に必要なクラス

それでは、このツリー構造をクラスで表すと、どのようになるでしょうか。
まず、画面が「動的に変化するかどうか」で大きく分かれます。動的に変化する画面の場合、 StatefulWidgetを継承したクラスを作成します。逆に、静的な画面であれば、 StatelessWidgetを継承したクラスを使用します。

StatefulWidgetを使用した画面の作り方

StatefulWidgetを使用する場合は、次の2つのクラスが必要です。

  • StatefulWidgetを継承したクラス
  • State<T>を継承したクラス

プロジェクト作成直後のコードを例に、解説します。まずは、 StatefulWidgetを継承した MyHomePageクラスを見てみましょう。
ccreateState()をオーバーライドし、後述する State<T>のインスタンスをセットします。

次に、State<T>を継承した _MyHomePageStateクラスを見ていきましょう。
まず、状態を保持しておくフィールド変数を定義します。 build()メソッドで、フィールド変数を使用して、Widgetを構築していきます。
フィールド変数を更新するときは、 setState()のクロージャ内で変数を更新すると、 Widget build(BuildContext context)がコールされWidgetが再構築されることで、UIが更新されます。

 

StatelessWidgetを使用した画面の作り方

StatelessWidgetを継承したクラスを作成します。 StatelessWidgetは状態を変化させることができません。そのため、 State<T>クラスは不要で、直接 build()メソッドを実装します。

 

画面遷移

画面遷移を行うには、 Navigatorクラスを使用します。

Push/Pop

画面遷移するには、 Navigator.push()メソッドを使用します。第2引数で MaterialPageRouteクラスを使い、次の画面のインスタンスを生成して渡します。

前の画面に戻るには Navigator.pop(context)と実装すればOKです。また、Push遷移すると、左上に戻るボタンが表示されるため、この機能で十分であれば、Pop遷移の実装は必要ありません。

Modal

モーダル遷移の場合も Navigator.push()を使用します。 fullscreenDialog引数を trueに設定すると、モーダル遷移になります。

値の渡し方

次の画面に値を渡すには、遷移先でプロパティを定義し、コンストラクタで値を渡します。
まず、遷移先のコードです。

nameをコンストラクタで受けとり、 Widget build(BuildContext context)内でテキスト表示しています。
プロパティを finalとしているため、コンストラクタの実装が必須となります。(ただし、後からプロパティの値を変更する場合は、 finalを付ける必要はありません)
次に、遷移元です。

プロジェクトテンプレートのHomePageを変更し、次の画面に値を渡すようにしました。
値を渡す際は、 MaterialPageRotue()で次の画面を生成する際、コンストラクタに値を渡すことで、実現できます。

値の戻し方

値を戻す際は、 Navigator.pop()メソッドに値を渡します。

次に、戻した値を受け取る実装です。

このサンプルでは、戻ってきた値を使用し、ボタンのテキストを変化させるようにしました。
戻り値の受取は非同期となるため、 awaitを使用します。また、 awaitを使用する場合は、関数を asyncとします。

Widget

Widgetは、FlutterのUIを定義するオブジェクトです。Widgetの特徴としては、UIのほぼ全てをWidgetやそのツリーで構成されていることが挙げられます。
また、ユーザ操作に対するレスポンスが優れているUI/UXが、Widgetとして数多く存在しています。また、その多くはカスタマイズ可能であり、もちろん自作のWidgetを作成することも可能です。
ここでは、使用頻度の高いWidgetを紹介します

レイアウト

Scaffold

画面の骨組みとなるレイアウトです。AppBar, FAB, BottomNavigationといった、基本的なUIの骨組みを提供します。基本的に、各画面のルートWidgetは、Scaffoldを使用することをお勧めします。

画面内のコンテンツは bodyに実装します。直接、UIパーツを置くと、1つしか配置できないため、後ほど説明する Columnなどを使用して、複数配置できるようにすることがほとんどです。

Container

様々な用途で使用できる、便利なWidgetです。色付きのボックス、サークルを作成したり、それを回転したりすることができ、柔軟にUIを表現することができます。

円形にするには、このようにします。

実行結果は次のようになります。

BoxDecorationクラスを使用して、円形を指定します。このとき、 Containercolor引数は渡さず、 BoxDecorationcolorを渡す必要があるため、注意してください。

Center

子Widgetをセンタリングして表示したいときに使用します。

childColumnRowといった、複数のWidgetを表示できるWidgetを渡すことで、複数パーツをセンタリングすることも可能です。

Column

UIパーツを縦に並べたいときに使用します。使い方はシンプルです。

Columnでは、子Widgetを複数持つことができるため、引数名が childrenとなり、Widget配列を渡します。

Row

UIパーツを横に並べたいときに使用します。

mainAxisAlignment: MainAxisAlignment.spaceEvenlyとすることで、均等にスペースを取るようにしています。

UIパーツ

Text

テキストを表示するために使用します。

ほとんどは、第一引数のテキスト指定のみで済みますが、フォントスタイルを設定したい場合は、 style引数に TextStyleを渡します。
TextStyleでは、フォントサイズ、太字・イタリック、カラーなどを設定できます。

Image

画像を表示するWidgetです。
まずは、アプリ埋め込みのアセットを表示する方法です。アセットを表示するには、画像を配置した後、 pubspec.yamlで登録する必要があります。

登録したアセットを表示するには、以下にようにします。

引数に、 pubspec.yamlで記載した画像のパスを渡します。

また、URLを指定して、画像をダウンロードして読み込むこともできます。

Flutterサンプルでお馴染みのフクロウが表示されます。

RaisedButton

立体的なボタンを表示します。テキストボタンの他に、 icon()ファクトリメソッドを使用することで、アイコン付きのボタンを表示することができます。

ボタンが押された時の処理は onPressedに、クロージャとして記載します。以下のように、別メソッドを作成して、呼び出すことも可能です。

なお、 StatelessWIdgetでは、 Widget build(BuildContext context)以外でBuildContextを取得することはできないため、ボタンタップ時にBuildContextが必要な場合(画面遷移など)は、クロージャで書くようにしてください。

TextField

TextFieldはテキスト入力UIを提供するWidgetです。

onSubmittedを実装し、入力した値を受け取ります。
また、 decoration引数に InputDecorationクラスを設定することで、TextFieldの見た目を設定できます。 このサンプルでは、labelTextではプレースホルダーを設定します。その他にも、 border: OutlineInputBorder()とすることで、枠付きの見た目にすることも可能です。

AppBar

AppBarは、画面上部に表示されるヘッダーです。

Scaffoldの apppBar引数に渡します。 actionsIconButtonを渡すと 、AppBar右側にボタンを追加することができます。

BottomNavigationBar

画面下部にタブのようなUIを表示することができます。

BottomNavigationを実装する際は、画面を切り替える処理は自分で実装する必要がある点に気をつけてください。今回の場合、画面のインスタンスを _children配列に保持し、Scaffoldで body: _children[_currentIndex],と渡すようにしています。
そして、BottomNavigationBarがタップされたときに呼ばれる _onBottomNavigationBarTap(int index)で、 _currentIndexを変更することで、画面を更新し、タブが切り替わったように見せています。そのため、BottomNavigationを使用する画面では、StatefulWidgetとなります。

自作Widgetの作り方

同じレイアウトを使いまわしたいときに、自作Widgetを作成するには、StatelessWiidgetもしくはStatefulWidgetを継承したクラスを作成します。

onPressedとchildは外部から設定できるよう、プロパティとコンストラクタを実装しています。そのほかは、これまで紹介したWidgetと同じように、 Widget build(BuildContext context)でWidgetを返却するようにします。

おまけ(PlantUML)

冒頭で示したWidgetツリー図は、PlantUMLで作成しました。記事画像用なので特にコードの整理はしていませんが、参考になればと思い、PlantUMLのコードを公開します。
ちなみに、冒頭で skinparam shadowing falseとすることで、デフォルトで描画される影を消去しています。

 

さいごに

Flutterは様々なWigetが用意されているされており、Wigetを組み合わせることでスピーディにクロスプラットフォームアプリが実現出来ることが分かりました。今後活用していきたいも思います!

おすすめ書籍

基礎から学ぶ Flutter Flutter モバイルアプリ開発バイブル プログラミング言語Dart

blog-page_footer_336




blog-page_footer_336




-iOS, Android
-, , ,

執筆者:


comment

メールアドレスが公開されることはありません。

CAPTCHA


関連記事

[Swift]MapViewでクラスタ機能を利用する。

1 はじめに2 クラスタリングとは3 PINのクラスタリング機能を利用する3.1 マップの作成3.2 PINの作成3.3 Pinのカスタマイズ3.4 カスタムしたPinの利用3.5 CustomPin ...

Android JavaでS3への画像アップロード

1 はじめに2 AWS上での事前準備3 Android StudioのGradleでAWS SDKをインストール4 ManifestにPermissionの追加5 カメラで写真を撮影し、保存先のPat ...

[初心者向け]Xcodeの使い方(よく使うショートカットキーとエディタ)

1 はじめに1.1 前提条件2 ショートカットキー2.1 コメントアウト2.2 インデント2.3 ファイル内検索2.4 プロジェクト内検索2.5 クリーン2.6 ビルド2.7 ラン3 エディタ3.1 ...

iOS Chartsライブラリを使い移動平均線を描画してみる。

1 はじめに2 Chartsライブラリについて2.1 ライブラリの導入2.2 描画の準備3 折れ線グラフを描画する3.1 LineChartViewの設定3.2 LineChart用のデータ作成3.3 ...

swift

[Swift4]UITextViewにプレースホルダをつける

1 はじめに1.1 前提条件2 実装3 さいごに はじめに こんにちは、nukkyです。 UITextFieldにはプレースホルダが標準で用意されていますが、UITextViewには用意されていません ...

フォロー

follow us in feedly

blog-page_side_responsive

2020年2月
 1
2345678
9101112131415
16171819202122
23242526272829

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。