Android
 Computer >> コンピューター >  >> プログラミング >> Android

【Android】左右・上下のスワイプ方向を検出する実装方法を解説

Androidでスワイプ方向(左・右・上・下)を検出するには?

この記事では、AndroidアプリにおいてGestureDetectorを使用し、ユーザーが画面をスワイプした方向(左・右・上・下)を検出して判定する方法を、ステップごとにわかりやすく解説します。

スワイプ操作は、画像の切り替えやリストの削除など、モダンなアプリでは欠かせないUIパターンです。本サンプルを実装すれば、4方向すべてのスワイプイベントを簡単にハンドリングできるようになります。

ステップ1:新規プロジェクトを作成する

まず、Android Studioを起動し、メニューから「File → New Project」を選択して新しいプロジェクトを作成します。必要な項目をすべて入力してプロジェクトのセットアップを完了させてください。

ステップ2:レイアウトファイル(activity_main.xml)を編集する

次に、res/layout/activity_main.xml に以下のコードを追加します。ここでは、RelativeLayoutの中に中央配置されたTextViewを置き、スワイプ操作を受け付ける画面を作成しています。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Swipe to Detect swipe Event"
        android:textSize="24sp"
        android:textStyle="bold" />
</RelativeLayout>

ステップ3:MainActivity.javaにスワイプ検出ロジックを実装する

続いて、src/MainActivity.java に以下のコードを記述します。ポイントは以下の通りです。

  • OnSwipeTouchListenerクラスでView.OnTouchListenerを実装し、タッチイベントをGestureDetectorに委譲します。
  • onFling()メソッド内で、X軸とY軸それぞれの移動距離(diffX / diffY)と速度(velocityX / velocityY)を比較し、どの方向へのスワイプかを判定します。
  • SWIPE_THRESHOLD(移動距離のしきい値:100px)とSWIPE_VELOCITY_THRESHOLD(速度のしきい値:100)を設けることで、意図しない軽いタッチをスワイプとして誤検出することを防ぎます。
  • 水平方向の移動が大きければ左右、垂直方向の移動が大きければ上下のスワイプとして処理されます。
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
    OnSwipeTouchListener onSwipeTouchListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        onSwipeTouchListener = new OnSwipeTouchListener(this, findViewById(R.id.relativeLayout));
    }
    public static class OnSwipeTouchListener implements View.OnTouchListener {
        private final GestureDetector gestureDetector;
        Context context;
        OnSwipeTouchListener(Context ctx, View mainView) {
            gestureDetector = new GestureDetector(ctx, new GestureListener());
            mainView.setOnTouchListener(this);
            context = ctx;
        }
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }
        public class GestureListener extends
         GestureDetector.SimpleOnGestureListener {
            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;
            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                boolean result = false;
                try {
                    float diffY = e2.getY() - e1.getY();
                    float diffX = e2.getX() - e1.getX();
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffX > 0) {
                                onSwipeRight();
                            } else {
                                onSwipeLeft();
                            }
                            result = true;
                        }
                    }
                    else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom();
                        } else {
                            onSwipeTop();
                        }
                        result = true;
                    }
                }
                catch (Exception exception) {
                    exception.printStackTrace();
                }
                return result;
            }
        }
        void onSwipeRight() {
            Toast.makeText(context, "Swiped Right", Toast.LENGTH_SHORT).show();
            this.onSwipe.swipeRight();
        }
        void onSwipeLeft() {
            Toast.makeText(context, "Swiped Left", Toast.LENGTH_SHORT).show();
            this.onSwipe.swipeLeft();
        }
        void onSwipeTop() {
            Toast.makeText(context, "Swiped Up", Toast.LENGTH_SHORT).show();
            this.onSwipe.swipeTop();
        }
        void onSwipeBottom() {
            Toast.makeText(context, "Swiped Down", Toast.LENGTH_SHORT).show();
            this.onSwipe.swipeBottom();
        }
        interface onSwipeListener {
            void swipeRight();
            void swipeTop();
            void swipeBottom();
            void swipeLeft();
        }
        onSwipeListener onSwipe;
    }
}

各スワイプイベントが検出されると、Toastで「Swiped Right」「Swiped Left」「Swiped Up」「Swiped Down」というメッセージが表示される仕組みになっています。実際のアプリでは、この部分を画面遷移やコンテンツの切り替えなどの処理に置き換えてください。

ステップ4:AndroidManifest.xmlを確認する

最後に、androidManifest.xml に以下のコードが正しく記述されていることを確認します。特別な権限は不要ですが、MainActivityがランチャーアクティビティとして登録されている必要があります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="app.com.sample">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

アプリを実行して動作を確認する

それでは、実際にアプリを起動して動作を確認してみましょう。実機のAndroidスマートフォンをPCに接続していることを前提に説明します。

Android Studioでプロジェクト内のアクティビティファイルを開き、ツールバーのRun(実行)アイコンをクリックしてください。デバイス選択ダイアログが表示されたら、接続済みのモバイル端末を選択します。アプリが起動すると、端末にはデフォルトの画面が表示されます。

【Android】左右・上下のスワイプ方向を検出する実装方法を解説

画面上で指をスワイプすると、スワイプした方向に応じて対応するToastメッセージが表示されれば、実装は成功です。しきい値(SWIPE_THRESHOLD や SWIPE_VELOCITY_THRESHOLD)の数値を調整することで、スワイプ判定の感度を自分のアプリに合わせてチューニングできます。

  1. iPhoneとAndroid間でファイルを共有する方法|アプリ・パソコン・iTunesを使った手順を解説

    「ねえ、音楽ファイルがどうしても共有できないんだけど。SHAREitとかXenderって聞いたことあるけど、どう思う?」——昨晩、友人からまたこんな質問を受けました。 スマートフォン市場において、iPhoneとAndroidはそれぞれ世界中に膨大なユーザーを抱えています。しかし、この2つのプラットフォーム間でスムーズにファイルを転送できるかというと、多くのユーザーにとって依然として悩みの種となっています。友人や家族と共有したい音楽ファイルや写真・動画がたくさんあるのに、なかなか上手くいかない——そんな経験はありませんか? こうした場面で役立つのが、SHAREitやXenderといったサードパー

  2. パソコンとAndroidスマホ間でファイルを転送する5つの方法【初心者向けガイド】

    最近Androidスマートフォンに機種変更した方や、新しいパソコンを購入した方は、いずれファイルのやり取りが必要になる場面に直面するでしょう。「やり方がわからない…」と不安になる必要はありません。この記事では、パソコンとAndroidスマホの間でファイルを転送するための基本的な方法を、初心者にもわかりやすく解説します。スマホとパソコンの間でファイルを移動したい理由はさまざまです。大切なデータをバックアップとしてパソコンに保存しておきたい、Androidスマホで編集したい画像ファイルをパソコンから受け取りたい――そんなときに役立つのがファイル転送です。ここでは、最もよく使われている代表的な方法を