Android OnTouch simultaneous touches - java

I have an OnTouchListener in my activity and it's set on a layout and 5 other buttons, if you press them one by one/alone they work perfectly but if I want to press a button down and still move my finger on the layout it won't work until I release my finger from the button.
How can I use OnTouch so it will be possible to use a few views at the same time?
#Override
public boolean onTouch(View v, MotionEvent event){
switch (v.getId()) {
case R.id.layout:
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// On click on screen
oldX = (int) event.getX(); // set first click X as old
oldY = (int) event.getY(); // set first click Y as old
isClicked = true;
return true;
}
else if (event.getAction() == MotionEvent.ACTION_MOVE) {
isClicked = false;
// On finger move on screen
newX = (int) event.getX(); // set current X
newY = (int) event.getY(); // set current Y
diff[0] = newX - oldX; // Set X difference
diff[1] = newY - oldY; // Set y difference
oldX = newX; // set current X as last X
oldY = newY; // set current Y as last Y
// Send to server
new UDP_handler(IPAddr, port).execute("MOVE|" + diff[0] + "," + diff[1]);
return true;
}
else if(event.getAction() == MotionEvent.ACTION_UP){
if (isClicked)
new UDP_handler(IPAddr, port).execute("CLICK|LC");
return true;
}
break;
case R.id.Button0:
if (event.getAction() == MotionEvent.ACTION_UP){
new UDP_handler(IPAddr, port).execute("CLICK|MUP");
return true;
}
break;
case R.id.Button1:
if (event.getAction() == MotionEvent.ACTION_UP){
new UDP_handler(IPAddr, port).execute("CLICKUP|LC");
return true;
}
else if(event.getAction() == MotionEvent.ACTION_DOWN){
new UDP_handler(IPAddr, port).execute("CLICKDOWN|LC");
return true;
}
break;
case R.id.Button2:
if (event.getAction() == MotionEvent.ACTION_UP){
new UDP_handler(IPAddr, port).execute("CLICK|MC");
return true;
}
break;
case R.id.Button3:
if (event.getAction() == MotionEvent.ACTION_UP){
new UDP_handler(IPAddr, port).execute("CLICK|RC");
return true;
}
break;
case R.id.Button4:
if (event.getAction() == MotionEvent.ACTION_UP){
new UDP_handler(IPAddr, port).execute("CLICK|MDOWN");
return true;
}
break;
default:
break;
}
return false;
}
(I want to press down R.id.button1 and move my finger on R.id.layout at the same time going through it's down and up actions as well)

Related

How to move image without using ACTION_MOVE?

When I open my app on the left top corner appears image, when I touch it image starts to move towards bottom right corner. Now when I stop moving my finger (while touching image) image stops as well, how to make image move without interruption?
img.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int X = (int) event.getX();
int Y = (int) event.getY();
int action = event.getAction();
imgX += 1;
imgY += 1;
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
if (X >= 0 && X <= img.getWidth() && Y >= 0 && Y <= img.getHeight()) {
img.setX(imgX);
img.setY(imgY);
}
else {
finish();
}
break;
case MotionEvent.ACTION_UP:
finish();
break;
}
return true;
}
});

Problems with Bitmap following my finger

I am trying to make a bitmap, stored in the class Player, follow my finger around without giving it the ability to "teleport". I first tried this block of code:
#Override
public boolean onTouchEvent(MotionEvent event) {
pointerX = (int)event.getX();
pointerY = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
pointerX = (int)event.getX();
pointerY = (int)event.getY();
if (player.playerAlive) {
if((event.getX() > player.getX() || event.getX() < player.getX() + player.getWidth()) &&
(event.getY() > player.getY() || event.getY() < player.getY() + player.getHeight())) {
isDown = true;
}
}
break;
case MotionEvent.ACTION_MOVE:
if(isDown){
player.move(true);
}
break;
case MotionEvent.ACTION_UP:
isDown = false;
break;
}
return true;
}
However I noticed that even the slightest shift of the finger when tapping will result in Action_MOVE, so I replaced the code in ACTION_MOVE to this:
if(isDown){
if(event.getX() < pointerX - 20 || event.getX() > pointerX + 20)
player.move(true);
if(pointerY < event.getY() - 20 || pointerY > event.getY() + 20)
player.move(true);
}
But this resulted in the player not moving at all, when before the player would follow the finger properly but it would also "teleport" if I tapped away from the player. How can I get rid of the "teleporting" behavior properly?
You're correct in using ACTION_MOVE, but you're comparing event.getX() to pointerX when pointerX is set equal to event.getX(). Did you mean to compare it to player.getX()?

Handling onTouch and onClick events properly in android

I am using following code to drag a View across the screen
tweatBtn.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
float currX,currY;
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN:
{
mPrevX = event.getRawX();
mPrevY = event.getRawY();
btnPrevX = tweatBtn.getX();
btnPrevY = tweatBtn.getY();
break;
}
case MotionEvent.ACTION_MOVE:
{
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth() + 80; // deprecated
int height = display.getHeight(); // deprecated
currX = event.getRawX();
currY = event.getRawY();
if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width)
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
else
{
if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10))
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
});
}
It works fine but sometimes when i lift the Finger it automatically triggers click.How can i improve?
You are returning always false at the end of the code. Which means the touchListener you have set is not handling the touch. Because of if it, View will consider any normal touch as click. What you should do is return True, when the view is dragged, else you should return False
boolean dragged = false;
ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
int minTouchSlop = viewConfiguration.getScaledTouchSlop();
.....
public boolean onTouch(View v, MotionEvent event)
{
float currX,currY;
int action = event.getAction();
switch (action ) {
case MotionEvent.ACTION_DOWN:
{
mPrevX = event.getRawX();
mPrevY = event.getRawY();
btnPrevX = tweatBtn.getX();
btnPrevY = tweatBtn.getY();
dragged = false; // global dragged variable
break;
}
case MotionEvent.ACTION_MOVE:
{
Display display = getActivity().getWindowManager().getDefaultDisplay();
int width = display.getWidth() + 80; // deprecated
int height = display.getHeight(); // deprecated
currX = event.getRawX();
currY = event.getRawY();
if(Math.abs(currX-mPrevX) > minTouchSlop || Math.abs(currY-mPrevY) > minTouchSlop)
dragged = true; // differntiate btw drag or click
if(tweatBtn.getY() > 80 && tweatBtn.getX() > 0 && tweatBtn.getX() < width)
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
else
{
if((btnPrevY + currY - mPrevY) > 70 && (btnPrevX + currX - mPrevX) > -10 && tweatBtn.getX() < (width - 10))
{
tweatBtn.setX(btnPrevX + currX - mPrevX);
tweatBtn.setY(btnPrevY + currY - mPrevY);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
break;
}
return dragged;
}

Collision Between 2 views in android

I have 2 views in android and they are dragable.I want to detect collision between them.
Currently I am using this code to detect collision but I don't think its working .Please suggest what need to check the collision.
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams ParamsA = (RelativeLayout.LayoutParams) view
.getLayoutParams();
ParamsA.leftMargin = X - _xDelta;
ParamsA.topMargin = Y - _yDelta;
ParamsA.rightMargin = -250;
ParamsA.bottomMargin = -250;
for (int i = 0; i < balls.size(); i++) {
if (balls.get(i).getTag() != view.getTag()) {
RelativeLayout.LayoutParams ParamsB = (RelativeLayout.LayoutParams) balls
.get(i).getLayoutParams();
Rect b = new Rect(ParamsB.leftMargin,ParamsB.topMargin,ParamsB.rightMargin,ParamsB.bottomMargin);
Rect a = new Rect(ParamsA.leftMargin,ParamsA.topMargin,ParamsA.rightMargin,ParamsA.bottomMargin);
if(a.intersect(b))
{
Toast.makeText(getApplicationContext(), "Collision Detected", Toast.LENGTH_SHORT).show();
}
}
}
view.setLayoutParams(ParamsA);
break;
}
// _root.invalidate();
return true;
}
"balls" is array of type "View" which are laying in the screen.
I just found solution myself it works perfect in all case.
public boolean CheckCollision(View v1,View v2) {
Rect R1=new Rect(v1.getLeft(), v1.getTop(), v1.getRight(), v1.getBottom());
Rect R2=new Rect(v2.getLeft(), v2.getTop(), v2.getRight(), v2.getBottom());
return R1.intersect(R2);
}

Android Multitouch - Second Finger ACTION.MOVE Ignored

The following code is what I've been trying to use for multitouch. Finger one is set correctly and moves around when I drag my finger. Finger two shows up and disappears when I touch and release my finger, but it never moves around. Any idea what's wrong?
I have read developers blog I still do not understand what the issues are.
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
int pointerId = event.getPointerId(pointerIndex);
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
if (pointerId == 0)
{
fingerOneDown = 1;
fingerOneX = event.getX(pointerIndex);
fingerOneY = event.getY(pointerIndex);
}
if (pointerId == 1)
{
fingerTwoDown = 1;
fingerTwoX = event.getX(pointerIndex);
fingerTwoY = event.getY(pointerIndex);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
if (pointerId == 0)
{
fingerOneDown = 0;
fingerOneX = event.getX(pointerIndex);
fingerOneY = event.getY(pointerIndex);
}
if (pointerId == 1)
{
fingerTwoDown = 0;
fingerTwoX = event.getX(pointerIndex);
fingerTwoY = event.getY(pointerIndex);
}
break;
case MotionEvent.ACTION_MOVE:
if (pointerId == 0)
{
fingerOneDown = 1;
fingerOneX = event.getX(pointerIndex);
fingerOneY = event.getY(pointerIndex);
}
if (pointerId == 1)
{
fingerTwoDown = 1;
fingerTwoX = event.getX(pointerIndex);
fingerTwoY = event.getY(pointerIndex);
}
break;
}
return true;
}
Nevermind this. I fixed it. The ACTION.MOVE event always gets zero as the pointerId for some strange reason. Because of this, you always have to recalculate the pointerId within the event as seen below:
case MotionEvent.ACTION_MOVE:
int pointerCount = event.getPointerCount();
for(int i = 0; i < pointerCount; ++i)
{
pointerIndex = i;
pointerId = event.getPointerId(pointerIndex);
Log.d("pointer id - move",Integer.toString(pointerId));
if(pointerId == 0)
{
fingerOneDown = 1;
fingerOneX = event.getX(pointerIndex);
fingerOneY = event.getY(pointerIndex);
}
if(pointerId == 1)
{
fingerTwoDown = 1;
fingerTwoX = event.getX(pointerIndex);
fingerTwoY = event.getY(pointerIndex);
}
}
break;

Categories

Resources