I am using an onTouchEvent
for in my MainActivity.class
. It's working fine : if the user make a double L with the fingers, I call a fragment.
I would like to use this onTouchEvent
in an other Activity
but I think it's dirty if I copy all my code.
Now for that I have created an implement TouchListenerImpl
for that :
class TouchListenerImpl implements View.OnTouchListener {
private boolean movingDownL, movingDownR, movingLeft, movingRight, movingSuccessL, movingSuccessR = false;
private Point oldCoordsL, oldCoordsR, startPointL, startPointR = new Point(0, 0);
private boolean admin_touch = false;
private OnLTouch callback;
void setCallback(OnLTouch c) {
callback = c;
}
interface OnLTouch {
void lTouchSuccess();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("debugTouch", "onTouch");
int pIndexL = event.findPointerIndex(event.getPointerId(0));
int pIndexR = 0;
if(event.getPointerCount() > 1) pIndexR = event.findPointerIndex(event.getPointerId(1));
if(event.getPointerCount() > 1 && event.getX(pIndexL) > event.getX(pIndexR)) {
int tmp = pIndexR;
pIndexR = pIndexL;
pIndexL = tmp;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
movingDownL = true;
movingDownR = true;
movingSuccessL = false;
movingSuccessR = false;
if(event.getPointerCount() > 1) {
startPointR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
oldCoordsR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
}
startPointL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
oldCoordsL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
break;
case MotionEvent.ACTION_MOVE:
int downMinDistance = 300;
int lnrInaccuracy = 10;
int downInaccuracy = 30;
if(event.getPointerCount() > 1) {
if(!movingDownR) {
if(Math.abs(oldCoordsR.x - event.getX(pIndexR)) < downInaccuracy &&
oldCoordsR.y < event.getY(pIndexR)) break;
if(Math.abs(oldCoordsR.y - event.getY(pIndexR)) < lnrInaccuracy &&
oldCoordsR.x > event.getX(pIndexR) && !movingRight) {
movingRight = true;
startPointR = new Point(new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR)));
}
} else {
if (Math.abs(oldCoordsR.x - event.getX(pIndexR)) > downInaccuracy ||
oldCoordsR.y < event.getY(pIndexR)) {
movingDownR = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= downMinDistance){
movingDownR = false;
}
}
}
if(!movingDownL) {
if(Math.abs(oldCoordsL.x - event.getX(pIndexL)) < downInaccuracy &&
oldCoordsL.y < event.getY(pIndexL)) break;
if(Math.abs(oldCoordsL.y - event.getY(pIndexL)) < lnrInaccuracy &&
oldCoordsL.x < event.getX(pIndexL) && !movingLeft) {
movingLeft = true;
startPointL = new Point(new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL)));
}
}else {
if (Math.abs(oldCoordsL.x - event.getX(pIndexL)) > downInaccuracy ||
oldCoordsL.y > event.getY(pIndexL)) {
movingDownL = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= downMinDistance){
movingDownL = false;
}
}
int lnrMinDistance = 50;
if(movingLeft) {
if (Math.abs(oldCoordsL.y - event.getY(pIndexL)) > lnrInaccuracy ||
oldCoordsL.x > event.getX(pIndexL)) {
movingLeft = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= lnrMinDistance) {
movingLeft = false;
movingSuccessL = true;
}
}
if(movingRight) {
if (Math.abs(oldCoordsR.y - event.getY(pIndexR)) > lnrInaccuracy ||
oldCoordsR.x < event.getX(pIndexR)) {
movingRight = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= lnrMinDistance) {
movingRight = false;
movingSuccessR = true;
}
}
if(movingSuccessL && movingSuccessR) {
if (!admin_touch)
{
admin_touch = true;
if (callback != null)
callback.lTouchSuccess();
}
}
oldCoordsL = new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL));
oldCoordsR = new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR));
break;
case MotionEvent.ACTION_UP:
movingDownL = false;
movingDownR = false;
movingLeft = false;
movingRight = false;
break;
default:
return false;
}
return true;
}
private double findDistance(Point p1, Point p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
}
In my Activity, I call the implement like this :
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
TouchListenerImpl imp = new TouchListenerImpl();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imp.setCallback(new TouchListenerImpl.OnLTouch() {
@Override
public void lTouchSuccess() {
Log.d("debugTouch", "WORKING !");
}
});
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("debugTouch", "onTouch");
return imp.onTouch(v, event);
}
}
The problem is I never enter in my logs. It's not working at all...
After the Math. abs() calls, you're essentially testing if their finger is farther down the screen than it is across the screen. Store the initial down coordinates as member variables and set them during ACTION_DOWN . You declared two floats (touchX and touchY) inside the onTouchEvent method.
You can use the ViewConfiguration class to access common distances, speeds, and times used by the Android system. "Touch slop" refers to the distance in pixels a user's touch can wander before the gesture is interpreted as scrolling.
You can react to touch events in your custom views and your activities. Android supports multiple pointers, e.g. fingers which are interacting with the screen. The base class for touch support is the MotionEvent class which is passed to Views via the onTouchEvent() method. you override the onTouchEvent() method.
onTouchEvent is a method implemented by the View, Activity and other base classes like LinearLayout, etc.. public boolean onTouchEvent(MotionEvent event) { throw new RuntimeException("Stub!" ); } you can override this method by any derived classes.
You could use @DrilonBlakqori solution with little modification.
Make a separate class containing common code but use a callback to make View
visible.
class TouchListenerImpl implements OnTouchListener {
private OnLTouch callback;
@Override
public boolean onTouch(View v, MotionEvent event) {
// all your code
...
if (callback != null)
callback.lTouchSuccess();
...
}
void setCallback(OnLTouch c) {
callback = c;
}
interface OnLTouch {
void lTouchSuccess();
}
}
In your MainActivity
, create a new instance of TouchListenerImpl
and setCallback
like
TouchListenerImpl imp = new TouchListenerImpl();
imp.setCallback(new OnLTouch() {
public void lTouchSuccess() {
frameLayoutAdmin.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction()
.replace(R.id.framelayout_admin,new AdminLoginFragment())
.commit();
img_close.setVisibility(View.VISIBLE);
}
});
And in MainActivity
, the View
on which you want to detect the double L on that View
set this listener on that View
.
view.setOnTouchListener(imp);
I assume you want to detect double L on the main layout. For that you can do
findViewById(R.id.mylayout).setOnTouchListener(imp);
I hope this solves your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With