edge swipe는 폰의 좌 혹은 우 경계에서 터치한 상태에서 화면 가운데쪽으로 드래그하는 동작을 말한다. 아이폰에서는 흔한 동작인데 안드로이드에서는 잘 볼 수 없는 패턴이다.
폰의 back key 오른쪽에 있을 때 폰을 왼손으로 쥐고 있거나 반대로 back key가 왼쪽에 있는데 폰을 오른속으로 쥐고 있는 경우 back key를 한 손으로 누르기가 힘들다. 이럴 때 edge 스와이프 동작을 back key의 기본 동작인 페이지 닫기를 동작시킨다면 앱의 사용성이 좋아진다.
EdgeSwipeHelper.java
package com.mdiwebma.base.helper;
import android.app.Activity;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import com.mdiwebma.base.BuildConfig;
import com.mdiwebma.base.R;
import com.mdiwebma.base.logging.Dlog;
import com.mdiwebma.base.utils.DisplayUtils;
/**
* @author djkim
*/
public class EdgeSwipeHelper extends GestureDetector.SimpleOnGestureListener {
public static interface EdgeSwipeListener {
void onEdgeSwipe(Activity activity, boolean leftEdgeToRightSwipe);
}
private static final EdgeSwipeListener DEFAULT_LISTENER = new EdgeSwipeListener() {
@Override
public void onEdgeSwipe(@NonNull Activity activity, boolean leftEdgeToRightSwipe) {
if (leftEdgeToRightSwipe) {
activity.finish();
activity.overridePendingTransition(android.R.anim.slide_in_left, R.anim.slide_out_right);
} else {
activity.finish();
activity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
}
};
private static final int SWIPE_EDGE_DISTANCE = 90;
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_DISTANCE = 200;
@NonNull
final Activity activity;
@NonNull
final GestureDetector gestureDetector;
@NonNull
EdgeSwipeListener listener = DEFAULT_LISTENER;
public EdgeSwipeHelper(@NonNull Activity activity) {
Dlog.assertNotNull(activity);
this.activity = activity;
this.gestureDetector = new GestureDetector(this);
}
public void setEdgeSwipeListener(@NonNull EdgeSwipeListener listener) {
Dlog.assertNotNull(listener);
this.listener = listener;
}
public boolean checkEdgeSwipe(MotionEvent me) {
return gestureDetector.onTouchEvent(me);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (e1 != null && e2 != null) {
float xDistance = Math.abs(e2.getX() - e1.getX());
float yDistance = Math.abs(e2.getY() - e1.getY());
if (BuildConfig.DEBUG) {
Log.v("EdgeSwipe", "e1 x=" + e1.getX() + " e1 rawX=" + e1.getRawX());
Log.v("EdgeSwipe", "e2 x=" + e2.getX() + " e2 rawX=" + e2.getRawX());
Log.v("EdgeSwipe", "xDistance=" + xDistance + " yDistance=" + yDistance);
Log.v("EdgeSwipe", " DisplayUtils.getDisplayWidth()=" + DisplayUtils.getDisplayWidth()
+ " velocityX=" + velocityX);
}
if (xDistance >= SWIPE_MIN_DISTANCE && yDistance <= SWIPE_MAX_DISTANCE) {
if (e1.getX() < e2.getX() && e1.getX() <= SWIPE_EDGE_DISTANCE) {
// left edge to right
listener.onEdgeSwipe(this.activity, true);
return true;
} else if (e1.getX() >= e2.getX() && e1.getX() >= DisplayUtils.getDisplayWidth() - SWIPE_EDGE_DISTANCE) {
// right edge to left
listener.onEdgeSwipe(this.activity, false);
return true;
}
}
}
return false;
}
}
helper의 사용은 간단하다. Activity에서 아래 코드만을 추가하면 된다.
final EdgeSwipeHelper edgeSwipeHelper = new EdgeSwipeHelper(this);
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
edgeSwipeHelper.checkEdgeSwipe(event);
return super.dispatchTouchEvent(event);
}