Skip to content

Instantly share code, notes, and snippets.

@hvnsweeting
Created March 16, 2012 16:21
Show Gist options
  • Save hvnsweeting/2050837 to your computer and use it in GitHub Desktop.
Save hvnsweeting/2050837 to your computer and use it in GitHub Desktop.
SmartOnTouchListener
/**
* @author Nguyen Viet Hung (hvnsweeting@gmail.com)
* @version 1.0
* SmartOnTouchListener class help convert your onTouch into single-click and drag&drop, double-click and drag&drop or long-click and drag&drop
*/
package com.aps.smartbar.quicksettings.service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Handler;
import android.os.Vibrator;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.ImageView;
import com.aps.smartbar.quicksettings.activity.MainActivity;
class SmartOnTouchListener implements OnTouchListener {
private WindowManager wm;
private WindowManager.LayoutParams params;
private Context context;
private SharedPreferences mPreferences;
private ImageView mIcon;
private long down = 0;
int action;
int choosed;
long downTime;
float mCurX, mCurY;
float downX, downY;
double movingDistance;
private final long VIBRATE_INTERVAL = 80;
private final long DOUBLE_CLICK_INTERVAL = 300;
private final int LONG_CLICK_INTERVAL = 190;
private final double MOVING_R = 15;
// private static final String TAG = "com.hvn.android";
int halfOfIconSize;
private long thisTime = 0;
private long lastTouchTime = 0;
Handler handler = new Handler();
Runnable singleClickTask = new Runnable() {
public void run() {
thisTime = System.currentTimeMillis();
startActivity(MainActivity.class);
vibrateIfHapticIsEnabled();
}
};
public SmartOnTouchListener(Context context, WindowManager wm,
WindowManager.LayoutParams params, SharedPreferences mPreferences,
ImageView mIcon) {
this.context = context;
this.wm = wm;
this.params = params;
this.mPreferences = mPreferences;
this.mIcon = mIcon;
halfOfIconSize = mPreferences.getInt("size", 25) / 2;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
action = event.getAction();
mCurX = event.getRawX();
mCurY = event.getRawY();
// You should choose click style somewhere and put value to preferences
choosed = mPreferences.getInt("click_style", 1);
if (choosed == 1)
return setOnSingleClickAndMove(event);
else if (choosed == 2)
return setOnDoubleClickAndMove(event);
else
return setOnLongClickAndMove(event);
}
private boolean setOnLongClickAndMove(MotionEvent event) {
if (action == MotionEvent.ACTION_DOWN) {
downX = event.getRawX();
downY = event.getRawY();
downTime = event.getEventTime();
movingDistance = 0;
// start MainActivity with timer
handler.postDelayed(singleClickTask, LONG_CLICK_INTERVAL);
} // ACTION_DOWN
if (action == MotionEvent.ACTION_MOVE) {
// MOVE View
moveView();
movingDistance = Math.sqrt((mCurX - downX) * (mCurX - downX)
+ (mCurY - downY) * (mCurY - downY));
if (movingDistance > MOVING_R) {
// cancel callback
handler.removeCallbacks(singleClickTask);
}// if
}// ACTION_MOVE
if (action == MotionEvent.ACTION_UP) {
// Cancel callback
handler.removeCallbacks(singleClickTask);
if (movingDistance > MOVING_R) {
putLastXYToPreference();
}
}// ACTION_UP
return false;
}// setOnLongClickAndMove
private boolean setOnDoubleClickAndMove(MotionEvent event) {
if (action == MotionEvent.ACTION_DOWN) {
vibrateIfHapticIsEnabled();
long now = System.currentTimeMillis();
thisTime = now;
if (thisTime - lastTouchTime < DOUBLE_CLICK_INTERVAL) {
// Double tap
handler.removeCallbacks(singleClickTask);
thisTime = System.currentTimeMillis();
startActivity(MainActivity.class);
// If is double tap, reset to start state.
lastTouchTime = -1;
return true;
} else {
// If not double tap (too slow or single click), save
// last state for next check
lastTouchTime = System.currentTimeMillis();
}// else
}// ACTION_DOWN
if (action == MotionEvent.ACTION_MOVE) {
params.x = (int) mCurX - halfOfIconSize;
params.y = (int) mCurY - halfOfIconSize;
wm.updateViewLayout(mIcon, params);
}// ACTION_MOVE
if (action == MotionEvent.ACTION_UP)
putLastXYToPreference();
return false;
}// setOnDoubleClickAndMove
private boolean setOnSingleClickAndMove(MotionEvent event) {
if (action == MotionEvent.ACTION_DOWN) {
vibrateIfHapticIsEnabled();
down = event.getEventTime();
} else if (action == MotionEvent.ACTION_MOVE) {
moveView();
} else if (action == MotionEvent.ACTION_UP) {
long up = event.getEventTime();
if (up < down + LONG_CLICK_INTERVAL) {
vibrateIfHapticIsEnabled();
startActivity(MainActivity.class);
}// if is normal click
else {
putLastXYToPreference();
}// else is moving action
}// ACTION_UP
return true;
}// setOnSingleClickAndMove
private void moveView() {
params.x = (int) mCurX - halfOfIconSize;
params.y = (int) mCurY - halfOfIconSize;
wm.updateViewLayout(mIcon, params);
}// moveView
private void vibrateIfHapticIsEnabled() {
if (mPreferences.getBoolean("haptic_feedback", false)) {
Vibrator vib = (Vibrator) context
.getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(VIBRATE_INTERVAL);
}// if hapticEnabled
}// vibrateIfHapticIsEnabled
private void putLastXYToPreference() {
Editor editor = mPreferences.edit();
editor.putFloat("x", (float) params.x);
editor.putFloat("y", (float) params.y);
editor.commit();
}// putLastXYToPreference
protected void startActivity(Class<MainActivity> class1) {
context.startActivity((new Intent(context, MainActivity.class))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP));
}// startActivity
}// SmartOnTouchListener
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment