Flutterでスマホを振る操作を実装 [shake]

スマートフォンアプリでは、

  • シェイクしてデバッグメニューを表示
  • シェイクしてフィードバック送信
  • シェイクしてゲーム操作
  • シェイクして画面更新
  • シェイクしてサプライズ演出

といった「端末を振る」ジェスチャーを活用するケースがあります。

Flutterでこれを実装する場合、加速度センサーを直接扱うこともできますが、閾値調整やノイズ除去など意外と面倒です。

そんな時に便利なのが shake です。

この記事では、Flutterでシェイク検知を簡単に実装できる「shake」の使い方や特徴を解説します。


shakeとは?

shakeは、スマートフォンの加速度センサーを利用してシェイク(端末を振る動作)を検知するFlutterパッケージです。

主な特徴は以下の通りです。

  • シェイク検知を数行で実装可能
  • X・Y・Z軸方向の判定
  • シェイク強度(Force)の取得
  • ノイズフィルタリング
  • 感度調整
  • Android / iOS / Web対応

最新版のv3では、シェイク方向や強度などの詳細情報を取得できるようになっています。


インストール

まずは pubspec.yaml に追加します。

dependencies:
  shake: ^3.0.0

その後、

flutter pub get

を実行します。


基本的な使い方

もっともシンプルな実装例はこちらです。

import 'package:shake/shake.dart';

late ShakeDetector detector;

@override
void initState() {
  super.initState();

  detector = ShakeDetector.autoStart(
    onPhoneShake: (ShakeEvent event) {
      print('Shake detected!');
    },
  );
}

@override
void dispose() {
  detector.stopListening();
  super.dispose();
}

端末を振ると onPhoneShake が呼び出されます。


ShakeEventから詳細情報を取得

v3.0以降では ShakeEvent が提供されています。

ShakeDetector.autoStart(
  onPhoneShake: (ShakeEvent event) {

    print(event.direction);
    print(event.force);
    print(event.timestamp);

  },
);

取得できる主な情報

direction
force
timestamp

これにより、

  • どの方向へ振られたか
  • どれくらい強く振られたか
  • いつ発生したか

まで取得できます。


シェイク方向を判定する

shakeの大きな特徴の一つが方向判定です。

ShakeDetector.autoStart(
  onPhoneShake: (ShakeEvent event) {

    switch (event.direction) {

      case ShakeDirection.x:
        print('左右に振った');
        break;

      case ShakeDirection.y:
        print('上下に振った');
        break;

      case ShakeDirection.z:
        print('前後に振った');
        break;

      case ShakeDirection.undefined:
        print('複雑な動き');
        break;
    }
  },
);

例えばゲームアプリなら、

  • 左右シェイクで攻撃
  • 上下シェイクでジャンプ

といった操作も実装できます。


感度を調整する

デフォルト設定では感度が高すぎたり低すぎたりする場合があります。

その場合は shakeThresholdGravity を調整します。

ShakeDetector.autoStart(
  shakeThresholdGravity: 2.0,
  onPhoneShake: (event) {
    print('Shake');
  },
);

値を小さくすると感度が高くなります。


連続検知を防ぐ

シェイク検知では、

1回振っただけなのに
何度も検知される

という問題が起きやすいです。

その場合は shakeSlopTimeMS を設定します。

ShakeDetector.autoStart(
  shakeSlopTimeMS: 500,
  onPhoneShake: (event) {},
);

これにより500ms以内の連続検知を無視できます。


複数回振った場合のみ反応

例えば、

「3回振ったらデバッグメニューを開く」

といった実装も可能です。

ShakeDetector.autoStart(
  minimumShakeCount: 3,
  onPhoneShake: (event) {
    openDebugMenu();
  },
);

誤検知を減らしたい場合に便利です。


ノイズフィルタリング

端末の移動や歩行中の揺れを誤検知するケースがあります。

その場合はフィルタリング機能を有効化します。

ShakeDetector.autoStart(
  useFilter: true,
  onPhoneShake: (event) {},
);

ノイズを軽減し、より安定したシェイク検知が可能になります。


デバッグメニューを表示する

実際のアプリでよく使われる活用例です。

ShakeDetector.autoStart(
  onPhoneShake: (event) {

    showModalBottomSheet(
      context: context,
      builder: (_) {
        return const DebugMenu();
      },
    );

  },
);

開発版アプリでは、

  • API切り替え
  • ログ確認
  • Feature Flag変更

などに利用できます。

Flutterコミュニティでも「シェイクでフィードバック画面やデバッグ画面を表示する」用途は人気があります。


フィードバック送信機能

ユーザーからの不具合報告にも利用できます。

ShakeDetector.autoStart(
  onPhoneShake: (event) {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) => FeedbackPage(),
      ),
    );
  },
);

実際にコミュニティでも「Shake to Report」のような仕組みを実装する事例が見られます。


主な設定項目

パラメータ説明デフォルト
shakeThresholdGravityシェイク感度2.7
shakeSlopTimeMS最小検知間隔500ms
shakeCountResetTimeカウントリセット時間3000ms
minimumShakeCount必要シェイク回数1
useFilterノイズフィルタfalse

用途に応じて細かく調整できます。


メリット

実装が非常に簡単

数行でシェイク検知を導入できます。

感度調整が可能

誤検知を抑えやすくなります。

シェイク方向を取得できる

X・Y・Z軸方向の判定が可能です。

Force情報も取得できる

強く振ったかどうかを判定できます。


注意点

実機テストが必須

シェイクは物理センサーを利用するため、エミュレーターでは十分にテストできません。

必ず実機で確認しましょう。

バッテリー消費に注意

常時センサー監視を行うため、

  • 必要な画面だけ有効化
  • 不要時は stopListening()

を呼び出すことをおすすめします。

ユーザーが気付かない可能性がある

シェイク操作は隠し機能になりやすいため、

  • デバッグ用途
  • 開発者向け機能
  • パワーユーザー向け機能

との相性が良いです。


まとめ

shakeは、Flutterでシェイクジェスチャーを簡単に実装できる定番パッケージです。

特に、

  • デバッグメニュー
  • フィードバック送信
  • ゲーム操作
  • イースターエッグ
  • 隠し機能

などの実装に最適です。

最新版では方向判定やForce取得にも対応しており、単なる「振ったかどうか」だけでなく、より高度なジェスチャー処理も実現できます。Flutterアプリにユニークな操作体験を追加したい場合は、ぜひ試してみてください。

タイトルとURLをコピーしました