Flutterでコンパスアプリを作ってリリースした話

# はじめに
個人開発でFlutterを使用して、コンパスアプリを作り、リリースしてみましたので、その実装方法や使用したライブラリなどを紹介してみようと思います。

# 作ったアプリ
作ったアプリはコンパスですが、ただのコンパスでなく、恵方巻コンパスです。
普通のコンパスとの違いは、「北を差すのでなく、恵方を差す」というだけです！

恵方巻コンパスアプリ自体は2年前にiOSアプリをリリースしていて、去年はAndroid版もリリースしていたのですが、今回はAndroid版のみFlutterで作り直してリリースしました。
<img width="543" alt="スクリーンショット 2020-02-15 6.18.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172962/b000f99a-105f-a55b-23c3-3ac9ca227e09.png">
[恵方巻コンパス2020](https://play.google.com/store/apps/details?id=kazu.com.ehoapp&hl=ja)

# Flutterで作った理由
自分は普段仕事でiOSアプリの開発を行っているので、iOSは慣れているですが、Androidについてはあまり詳しくないです。
詳しくないながらも、去年kotlinで作ってリリースしたのですが、今年、恵方の方向を2020年版にアップデートしようと思ったところ、APIレベルの更新やAndroidX対応など案外とやることがありそうだったので、どうせならFlutterで作り直した方が簡単に出来るのではと思ったことが、今回、Android版のみをFlutterで作った理由です。（Flutterを触ったことがあったのも理由の一つです。）

# Flutterでコンパスの実装方法
まず、Flutterでコンパスアプリを作るにはどうしたらよいか検索したところ、flutter_compassというライブラリを使用してコンパスアプリを作る記事があり、それを参考に実装しました。

[参考にした記事](https://itnext.io/build-a-compass-app-in-flutter-b49a78aa951d)

## サンプルコード
恵方を指すコンパス自体は、50行くらいで実装できます。
参考にした記事のコードを[provider](https://pub.dev/packages/provider)を使用して、シンプルに書き換えてみました。

```dart
class CompassPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Compass>(
      create: (_) => Compass(),
      child: Consumer<Compass>(
        builder: (context, compass, child) {
          return Scaffold(
            appBar: AppBar(
              title: Text('タイトル'),
            ),
            body: Center(
              child: Transform.rotate(
                angle: compass.angle,
                child: Image.asset(
                  'images/arrow.png',
                  width: 100,
                  height: 100,
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

class Compass with ChangeNotifier {
  static const ehoAngle = 255.0;

  double _angle = 0;
  double get angle => _angle;

  Compass() {
    FlutterCompass.events.listen((value) {
      _angle = -1 * pi * ((value - ehoAngle) / 180);

      notifyListeners();
    });
  }
}
```

[github](https://github.com/yakazu/flutter_eho_app)に公開しておきました。

### flutter_compass
FlutterCompassのイベントをlistenしておくと、端末の方向が変わる度に、呼び出されます。
角度が取得できるので、それをラジアンに変換し、notifyListenersで画面に通知しています。ラジアンに変換する際に、実際の角度から恵方の角度を引いた値を指定しています。（2020年の恵方は255度なので、255を引いています。）

```dart
FlutterCompass.events.listen((value) {
    _angle = -1 * pi * ((value - ehoAngle) / 180);

    notifyListeners();
});
```

[flutter_compass](https://pub.dev/packages/flutter_compass)

### Transform.rotate
Transform.rotateを使用して、画像を傾けて表示しています。

```dart
Transform.rotate(
    angle: compass.angle,
    child: Image.asset(
        'images/arrow.png',
        width: 100,
        height: 100,
    ),
),
```

[Transform.rotate constructor](https://api.flutter.dev/flutter/widgets/Transform/Transform.rotate.html)

# その他、使用したライブラリ
## flutter_launcher_icons
アイコンを簡単に作成できるライブラリです。
https://pub.dev/packages/flutter_launcher_icons

## simple_animations
アニメーションを実装するために使用しました。
https://pub.dev/packages/simple_animations

## vibration
バイブレーションを実装するために使用しました。
https://pub.dev/packages/vibration

## firebase_admob
admobの広告を出すためのライブラリです。
https://pub.dev/packages/firebase_admob

# 最後に
今回紹介したAndorid版のアプリは2000ダウンロード程度でした。
iOS版は1日で40000ダウンロードされたので、恵方巻という完全に日本人向けのアプリでは、iOSの方がまだまだ有利なのかなと感じました。

Flutterはマルチプラットフォームのframeworkですが、iOS、Androidのどちらかのみをリリースしているアプリの場合、リリースしていない方をFlutterで開発してみるのは、学習コストや将来性の面でもありかなと思いました。(良い感じに出来たら、その後は両OSをFlutterに移行する事も可能ですし！)