Android EngineerがFlutterという新世界に踏み込んだ話

この記事は[Recruit Engineers Advent Calendar 2018](https://adventar.org/calendars/3063#list-2018-12-04) の6日目の記事です。

初めまして。 Bing です。
Airレジ海外のAndroid開発をやっています。現在職場で新規案件と大規模リファクタリングは全部Kotlinでやっています。Javaコードと比べると、30%~50%ぐらいのコード量が削減できるなんて、すごく楽しいです。
Androidエンジニアとしては100%Kotlinが好きだと言えますが、最近Flutterへの気持ちがどんどん増えてきてしまっています(笑)。
このブログを通じて、浅いかもしれませんが、私が半年ぐらいFlutterを触ってきた経験を話したいです。

ちなみにちょうど12.4の[Flutter Live   |  Google Developers](https://developers.google.com/events/flutter-live/)は公開されて、Flutter Release 1.0も発表されました！🎉🎉🎉興味がある方ぜひご覧ください。
（デザインとアニメーションツール[Flare](https://medium.com/2dimensions/flare-launch-d524067d34d8)とDesktop Application Platform [Hummingbird](https://medium.com/flutter-io/hummingbird-building-flutter-for-the-web-e687c2a023a8)もリリースされて、面白いと思います。）

## Flutterとはなに？
FlutterはGoogleによって開発されたクロスプラットフォームフレームワークです。iOSとAndroid両方を同じコードで対応することができます。
Flutterの公式サイトにこう書いてあります：
> Flutter allows you to build beautiful native apps on iOS and Android from a single codebase.

統一コードで違うプラットフォーム対応、綺麗なUI、効率的なコーディング、それはflutterが自慢できる三大特徴であります。
## なぜflutter ?
私がプライベートでiOS、Android両方を開発する必要があって、時間を削減するためReact Native（RN）とFlutter両方を検討しました。

正直JavaScriptをちょっとみたらアプリ開発者として勉強コストがたかそうですぐ辞めたい気持ちがでました（笑）。
その時Airbnbの有名な[RNを全体切り替える](https://medium.com/airbnb-engineering/sunsetting-react-native-1868ba28e30a)のニュースが話題になりました。

私がAirbnbのテックブログを読んだ後、真面目にRNとFlutterの比べる記事を大量に探してみて、Material Design基準的なUIと描画速度的にどっちでもFlutterの勝ちで、Dartの書き方はJavaと似てて、flutterでアプリを作ろうの思いがでました。

そのTechnology Structure的に、RNがnative view(iOS & Android)を依存して実装するより、flutterは自分で[Skia](https://skia.org/dev/flutter)でUIを描いてるのがすごいと思います。依存してないから自由度と実際の性能的に、ちょっと複雑の同じのUIを実装すると感じられると思います。
一方的に、Flutterは全部自分でUIを描くのが新しいチャンレンジですので、今はもちろん完璧ではないです。それはあとで細かく話させていただきます。
<img width="619" alt="Screen Shot 2018-12-05 at 22.45.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/147053/094d9cdd-b3aa-3388-2fed-960b2a8eb7b4.png">
## Android開発からみると新しい視点

C, C++以外はAndroidだけやってきましたから、こちらはAndroid開発から見たFlutterの新しい視点だけ紹介します。iOS, Frontendの開発者としては結構普通なことかもしれませんが御了承ください。
### iOSはすぐ出来たんだ！
[公式Get Started](https://flutter.io/docs/get-started/install)による2時間ぐらいで起動できます。元々iOSできない私的に達成感がすごく大きいでした（笑）。
私の開発環境はAndroid Studioですが、Default SimulatorはiPhone Xになっていて、他のAndroid & iPhoneの端末もたくさん設定できます。
<img width="618" alt="Screen Shot 2018-12-05 at 22.45.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/147053/b45985c8-b79b-65b1-a418-a646114c96d3.png">
### Hot Reloadが楽！
Flutterが自慢してる開発効率をあげるHot Reloadとは、
開発途中で修正したコードはすぐ実機に或いはSimunatorに反映られる機能です。
そのスピードは何百msぐらいで、Android Instant Runより速い感じがあります。

### 言語はDart !
Dartは元々不人気だったけど、Flutterで人気が上がったみたいです（笑）。実際DartはKotlinとほぼ同じ時期に出て、性能と効率性もよくて、Server/App/Webで使われています。
ただ、笑い話みたいですが、Dartを使う一番の理由が「Dart開発チームと距離近い」だと[公式FAQ](https://flutter.io/docs/resources/faq#why-did-flutter-choose-to-use-dart)にも書いてあります。

Androidの基本の.xml＋.java (.kt)はひとつの.dartファイルになっていて、コード量を大分減らしましたが、FlutterにDartの書き方はさすがに括弧が多すぎじゃないかなと感じています。

```dart
        Align(
          alignment: Alignment.center,
          child: Padding(
            padding: const EdgeInsets.only(top: 60.0, left: 8.0, bottom: 16.0),
            child: new Container(
              width: 80.0,
              height: 80.0,
              decoration: new BoxDecoration(
                color: const Color(0xff7c94b6),
                image: new DecorationImage(
                  image: new AssetImage('images/cat.png'),
                  fit: BoxFit.cover,
                ),
                borderRadius:
                new BorderRadius.all(new Radius.circular(50.0)),
              ),
            ),
          ),
        ),
```
↑　一つの画像の表示でもそうなります。全画面のviewをかくとすごく行数と括弧になっちゃいます（笑）。
どんどん慣れてきても、UIの調整はそんなにやりやすくないだし、Flutter InspectorというUI確認ツールがあっても、Android Previewよりまだまだですかな。
### なんでもWidget !
AndroidはLayoutは画面構成、Viewは中の表示内容、AttributionはLayout或いはViewの属性であります。
Flutterは `なんでもWidget！` が基本概念です。Layout、View、Attribution、アプリ全体まではWidgetです。それが括弧が多くなる一つの理由だと思います。上のコードが例として、ImageのAlign/Padding/Decorationを設定したい場合、Imageを含めて四つのWidgetが必要になります。

ちなみに、Widgetの表示はStateで管理されています。それによるStatelessWidgetとStatefulWidgetが分けられています。
StatelessWidgetは静的なUI表示であり、StatefulWidgetはviewとdataを分離するため、stateでUI表示を管理しています。非同期の場合が難しいけど、Reactiveのサポートも豊富です。詳しくはこちら[RxDart](https://pub.dartlang.org/packages/rxdart)を参考にしてください。
<img width="620" alt="Screen Shot 2018-12-05 at 22.45.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/147053/a8b7c64f-d108-3f7b-86f1-73baddc35504.png">
## 開発中の色々
### Libraryはまだ発展中
最初アプリを作る準備をするとき、ライブラリーが充実しているかの調査をしました。
[Flutter Packages](https://pub.dartlang.org/flutter) はライブラリー検索ウェブで、基本機能が結構含まれています。

たとえば、Shared Preferences、SQLite、チャット、Bluetoothまでがサポートされています。特にグーグル公式だから、Firebaseのサポートがすごく豊富です。

ただ、発展中の技術として、すぐ変わったり更新したり中止したりのことがもちろんです。開発中はこんな変化をきちんと把握しないといけないです。

たとえば、半年前地図機能を実装したかったですが、検索したら公式サポートが無かったから[map_view](https://pub.dartlang.org/packages/map_view#-readme-tab-)が一番人気で必要な機能がまあまあ満足できるみたくて、無事に導入しました。
<img width="200" alt="Screen Shot 2018-12-05 at 22.45.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/147053/a9141624-32f6-d3ad-4db0-03b8832785a9.png">
実際に動くと、位置の更新はガツガツの感じがあって、グーグル地図の写真を一枚一枚で摂って表示してたそうです。それともユーザーアイコンのカスタマイズ定義ができないです。
その時友人からこのライブラリーもうメンテされてないよと言われて、GitHubで見ると本当にそう書いてあります。

いいことは同じ開発グループはすでに新しいPackage [flutter_map](https://pub.dartlang.org/packages/flutter_map)が提供されています。実行方法はもっとNativeで、カスタマイズが様々ができます。
その直前後[グーグル公式Plugin](https://medium.com/flutter-community/exploring-google-maps-in-flutter-8a86d3783d24)も発表されました。

ライブラリーの移行がめんどくさいけど、こんな近いところに技術の速い更新を感じするのが面白いです。
### Nativeと同じ画面を作ってみると
こちらは100枚のネットイメージを表示するリストを簡単に作成して、KotlinとFlutterのUIを比較してみました。
![111.gif](https://qiita-image-store.s3.amazonaws.com/0/147053/202fdfdf-3d5d-f2e4-067e-3a08c6522f72.gif)![222.gif](https://qiita-image-store.s3.amazonaws.com/0/147053/180550ea-03b9-8b85-1c32-23e0df92c35b.gif)
(左はKotlinで、右の方はFlutterです。)

結局はそんなにさがないように感じました。一般的な画面なら描画性能はNativeとほぼ一緒だと言えるでしょう。その上に、Flutterの方がDefault UIとアニメーションでもよくてきて、気持ちいいです。
## まとめ
Android Material Design、 iOS Cupertino、 他のUIテーマが提供してくれて、綺麗なUIとアニメーションの実装が本当にやりやすくなりました。
Structure的に性能が結構よくて、一般的なUI描画と変更がいい品質が出せます。
Hot reloadなどの開発サポートがあって、開発の効率もいい感じです。

この半年間で触ってきたら、新鮮感とこだわりポイントが確実にあって、Flutterの未來をワクワク期待しています。

## オススメリンク
1. [公式リンク](https://flutter.io/)：すごくいい資料で、get startからいろんな実装方法まで絶賛オススメです！
2. [FAQ  - Flutter](https://flutter.io/docs/resources/faq#introduction) ：FAQにみんなきになる質問は予想以上まとまれています。
3. [my  favourite list of flutter resources](https://medium.com/coding-with-flutter/my-favourite-list-of-flutter-resources-523adc611cbe)
4. [Widget カタログ](https://flutter.io/docs/development/ui/widgets) 
5. [Package探す窓口](https://pub.dartlang.org/flutter/packages?q=)
6. [Udacityのon-line教育](https://classroom.udacity.com/courses/ud905)：Google公式の講演、結構分かりやすい方で説明してくれる

ご精読ありがとうございました！