Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

안드로이드에서 좌우·상하 스와이프 방향 감지하기 — GestureDetector 완전 정리

이 튜토리얼에서는 안드로이드 앱에서 사용자가 화면을 왼쪽/오른쪽, 위/아래로 스와이프했을 때 그 방향을 감지하는 방법을 단계별로 알아봅니다. 스와이프 제스처는 이미지 갤러리, 뉴스 피드, 잠금 해제 화면 등 다양한 UI에서 활용되는 핵심 기능입니다.

핵심 원리: GestureDetector와 onFling()

안드로이드에서는 GestureDetector 클래스와 SimpleOnGestureListeneronFling() 콜백을 사용해 스와이프를 감지합니다. 터치 시작 지점과 끝 지점의 X/Y 좌표 차이를 계산하고, 미리 정의한 거리 임계값(SWIPE_THRESHOLD)속도 임계값(SWIPE_VELOCITY_THRESHOLD)을 넘는지 확인하여 방향을 판정합니다.

1단계 — 새 프로젝트 생성

Android Studio에서 File → New Project를 선택하고, 필요한 정보를 모두 입력하여 새 프로젝트를 생성합니다.

2단계 — 레이아웃 작성 (res/layout/activity_main.xml)

메인 레이아웃에 중앙에 안내 문구가 있는 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단계 — 메인 액티비티 구현 (src/MainActivity.java)

아래 코드는 스와이프 감지 로직 전체를 담고 있습니다. 내부 클래스 OnSwipeTouchListener가 터치 이벤트를 가로채고, GestureListeneronFling()에서 방향을 계산합니다.

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;
    }
}

동작 방식 살펴보기

  • X축 이동량이 Y축보다 크면 → 좌우 스와이프로 판정합니다. diffX > 0이면 오른쪽, 아니면 왼쪽입니다.
  • Y축 이동량이 더 크면 → 상하 스와이프로 판정합니다. diffY > 0이면 아래쪽(손가락이 아래로 이동), 아니면 위쪽입니다.
  • 두 축 모두 이동량이 100px 이상이고 속도도 100 이상일 때만 유효한 스와이프로 인식하므로, 단순한 터치나 느린 드래그는 무시됩니다.

4단계 — 매니페스트 설정 (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 Studio 툴바에서 Run 아이콘을 클릭하고, 목록에서 자신의 모바일 기기를 선택하세요. 앱이 실행되면 화면에 기본 안내 문구가 표시되며, 사방으로 스와이프할 때마다 해당 방향을 알려주는 토스트 메시지가 나타납니다.

안드로이드에서 좌우·상하 스와이프 방향 감지하기 — GestureDetector 완전 정리

마무리 및 활용 팁

이 예제는 토스트 메시지만 표시하지만, onSwipeListener 인터페이스를 구현하면 각 방향에 맞는 실제 동작(화면 전환, 슬라이드 메뉴 열기, 카드 넘기기 등)을 자유롭게 연결할 수 있습니다. 임계값을 조정하면 민감도도 쉽게 바꿀 수 있으니, 여러분의 앱 UX에 맞게 응용해 보세요.