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()?
Related
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;
}
});
I have a problem and I am stuck at this point. I used recyclerview swipe on each item of recyclerview. What I need to do is to update the textview with 1, 2 and so on as the swipe is moving right just like this.
I am getting the x-axis value with event.getRaw(x) and i need to increase the amount as the x value is increasing from left to right and decrease the count if the swipe is moving from right to left. Here is my code.
holder.swipeLayout.setOnTouchListener(new View.OnTouchListener() {
int downX, upX, initialX = 0, rightX;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getRawX();
startY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float x = event.getRawX();
float y = event.getRawY();
// Calculate move update. This will happen many times
// during the course of a single movement gesture.
scrollByX = x - startX; // move update x increment
scrollByY = y - startY; // move update y increment
startX = x; // reset initial values to latest
startY = y;
if (scrollByX >= 100 && scrollByX < 150)
holder.leftTextView.setText("1");
if (scrollByX >= 150 && scrollByX < 200)
holder.leftTextView.setText("2");
if (scrollByX >= 200 && scrollByX < 250)
holder.leftTextView.setText("3");
if (scrollByX >= 250 && scrollByX < 300)
holder.leftTextView.setText("4");
if (scrollByX >= 350 && scrollByX < 400)
holder.leftTextView.setText("5");
break;
case MotionEvent.ACTION_UP:
upX = (int) event.getX();
Log.i("event.getX()", " upX " + downX);
holder.swipeLayout.animateReset();
//holder.leftTextView.setText("0");
scrollByX = 0;
scrollByY = 0;
if (upX - downX > 100) {
// swipe right
}
else if (downX - upX > -100) {
// swipe left
}
break;
}
return false;
}
});
Every time i swipe these items sometimes it shows 1 and sometimes 5 meaning it is not behaving properly. Can someone please help me get through this. Thanks.
Try Updating the textView in onTouchEvent()'s case MotionEvent.ACTION_MOVE
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;
}
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)
zoom jumps around when I remove my finger and put it again ! anybody knows the problem ?
boolean surfaceTouchEvent(MotionEvent event) {
pointNum=event.getPointerCount();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_DOWN:
// User is pressing down another finger.
float x11 = event.getX(0) - event.getX(1);
float y22 = event.getY(0) - event.getY(1);
z4 = sqrt(x11*x11+y22*y22);
break;
case MotionEvent.ACTION_POINTER_UP:
// User is released one of the fingers.
break;
case MotionEvent.ACTION_MOVE:
if (pointNum >= 2 ) {
x1=event.getX(0);
x2=event.getX(1);
y1=event.getY(0);
y2=event.getY(1);
float x = event.getX(0) - event.getX(1);
float y= event.getY(0) - event.getY(1);
float z3 = sqrt(x*x+y*y);
if (pointNum >= 2 ) {
if ( z3 < z4 ) {
zoom = z3/z4;
}
else {
zoom = z3/z4;
}
zoom = constrain(zoom, 0, 100);
}
press1=event.getSize(0);
press2=event.getSize(1);
}
break;
}
return super.surfaceTouchEvent(event);
}