Skip to content

Instantly share code, notes, and snippets.

@yung-yu
Created June 8, 2017 10:20
Show Gist options
  • Save yung-yu/7abd25dc8562a5f45db34f2a466af5a0 to your computer and use it in GitHub Desktop.
Save yung-yu/7abd25dc8562a5f45db34f2a466af5a0 to your computer and use it in GitHub Desktop.
import android.animation.Animator;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import java.util.Timer;
import java.util.TimerTask;
public class TouchMoveGesture implements View.OnTouchListener {
private final static String TAG = "TouchMoveGesture";
private final static int TIME_OUT = 0;
private View touchView;
private View moveView;
private float touchX = -1;
private float touchY = -1;
private int curX = -1;
private int curY = -1;
private Timer timer;
private OnTouchListener listener;
private int timeOut = -1;
private boolean isEnableTimer = false;
public interface OnTouchListener {
void onMoveChange(int x, int y);
void onTouchUpTimeOut();
void onMoveItemClick();
void onMoveItemLongClick();
void onTouchDown();
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == TIME_OUT) {
if (listener != null) {
listener.onTouchUpTimeOut();
}
}
}
};
public TouchMoveGesture(View touchView, View moveView, int touchTimeOut) {
this.touchView = touchView;
this.moveView = moveView;
touchView.setOnTouchListener(this);
this.timeOut = touchTimeOut;
}
public void setEnableTouchTimer(boolean enableTimer) {
isEnableTimer = enableTimer;
if (!isEnableTimer) {
if (timer != null) {
timer.cancel();
timer = null;
}
} else {
if (timer == null) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (handler != null) {
handler.sendEmptyMessage(TIME_OUT);
}
}
}, timeOut);
}
}
}
public void setListener(OnTouchListener listener) {
this.listener = listener;
}
private float startX = -1;
private float startY = -1;
private long downTime = -1;
@Override
public boolean onTouch(View v, MotionEvent event) {
float x = event.getRawX();
float y = event.getRawY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d(TAG, "ACTION_DOWN");
if (timer != null) {
timer.cancel();
timer = null;
}
if (listener != null) {
listener.onTouchDown();
}
if (checkIsTouchItem(x, y)) {
startX = x;
startY = y;
downTime = System.currentTimeMillis();
touchPosition(x, y);
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.d(TAG, "ACTION_MOVE");
if (timer != null) {
timer.cancel();
timer = null;
}
if (checkIsTouchItem(x, y)) {
updatePosition(x, y);
return true;
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d(TAG, "ACTION_UP");
if(isActionClick(startX, startY, x, y)){
long curTime = System.currentTimeMillis();
if(curTime - downTime < ViewConfiguration.getLongPressTimeout()){
if (listener != null) {
listener.onMoveItemClick();
}
} else {
if (listener != null) {
listener.onMoveItemLongClick();
}
}
}
if (isEnableTimer) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (listener != null) {
listener.onTouchUpTimeOut();
}
}
}, timeOut);
}
startX = -1;
startY = -1;
downTime = -1;
curX = -1;
curY = -1;
}
return false;
}
private boolean isActionClick(float startX, float startY, float endX, float endY) {
if(startX == -1 || startY == -1){
return false;
}
float differenceX = Math.abs(startX - endX);
float differenceY = Math.abs(startY - endY);
if (differenceX > 10 || differenceY > 10) {
return false;
}
return true;
}
public void release() {
if (touchView != null) {
touchView.setOnTouchListener(null);
touchView = null;
}
moveView = null;
listener = null;
if (handler != null) {
handler.removeCallbacksAndMessages(null);
handler = null;
}
if (timer != null) {
timer.cancel();
timer = null;
}
}
private void touchPosition(float x, float y) {
int[] targetPosition = getMoveViewPosition();
touchX = x - targetPosition[0];
touchY = y - targetPosition[1];
}
private int[] getMoveViewPosition() {
int[] targetPosition1 = new int[2];
moveView.getLocationInWindow(targetPosition1);
int[] targetPosition2 = new int[2];
touchView.getLocationInWindow(targetPosition2);
return new int[]{targetPosition1[0] - targetPosition2[0],
targetPosition1[1] - targetPosition2[1]};
}
private boolean checkIsTouchItem(float x, float y) {
if (moveView == null) {
return false;
}
int targetWidth = moveView.getWidth();
int targetHeight = moveView.getHeight();
int[] targetPosition = getMoveViewPosition();
return targetPosition[0] < x && targetPosition[1] < y
&& targetPosition[0] + targetWidth > x && targetPosition[1] + targetHeight > y;
}
private void updatePosition(float x, float y) {
if (touchX == -1 || touchY == -1) {
return;
}
int targetWidth = moveView.getWidth();
int targetHeight = moveView.getHeight();
int changeX = (int) (x - touchX);
int changeY = (int) (y - touchY);
if (changeX < 0) {
changeX = 0;
} else if (changeX + targetWidth > touchView.getWidth()) {
changeX = touchView.getWidth() - targetWidth;
}
if (changeY < 0) {
changeY = 0;
} else if (changeY + targetHeight > touchView.getHeight()) {
changeY = touchView.getHeight() - targetHeight;
}
if (curX != changeX || curY != changeY) {
curX = changeX;
curY = changeY;
if (listener != null) {
listener.onMoveChange(changeX, changeY);
}
}
}
public void changeToolsVisibility(final View view, boolean isShow) {
if (isShow) {
if (view.getVisibility() != View.VISIBLE) {
view.animate().alpha(0).alpha(1).setDuration(300).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
view.setVisibility(View.VISIBLE);
view.clearAnimation();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
} else {
if (view.getVisibility() != View.GONE) {
view.animate().alpha(1).alpha(0).setDuration(300).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
view.setVisibility(View.GONE);
view.clearAnimation();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment