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
Related
I have to an ImageView named imgForeground which can be rotated, zoomed and moved but it can move to outside the screen. how can I restrict its movement not to go outside of screen? Is there any library for this? it is something like the apps that you can select a label, move and resize it and place it everywhere you want.
<ImageView
android:id="#+id/imgForground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="#drawable/icon" />
This code for zoom, move and rotate:
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale;
// Dump touch event to log
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
d = rotation(event);
break;
case MotionEvent.ACTION_UP: //first finger lifted
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null) {
newRot = rotation(event);
float r = newRot - d;
matrix.postRotate(r, view.getMeasuredWidth() / 2,
view.getMeasuredHeight() / 2);
}
}
break;
}
// Perform the transformation
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
/**
* Show an event in the LogCat view, for debugging
*/
private void dumpEvent(MotionEvent event) {
String names[] = {"DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?"};
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
Log.d(TAG, sb.toString());
}
Mobile device screen is a region of plane(x,y) where (0,0) coordinate is top-left corner. You need to calculate the imageView position w.r.t screen region. In your event handler, get the position of your imageView.
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
Now get the displayed size of an image inside the image view.
int ih=view.getMeasuredHeight();//height of imageView
int iw=view.getMeasuredWidth();//width of imageView
int iH=view.getDrawable().getIntrinsicHeight();//original height of underlying image
int iW=view.getDrawable().getIntrinsicWidth();//original width of underlying image
if (ih/iH<=iw/iW)
iw=iW*ih/iH; //rescaled width of image within ImageView
else
ih= iH*iw/iW; //rescaled height of image within ImageView
Now get the width and height of screen
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int deviceHeight = displayMetrics.heightPixels;
int deviceWidth = displayMetrics.widthPixels;
If imageView moves towards left
if(x>0)
//Move towards left functionality
If imageView moves towards top
if(y>0)
//Move towards top functionality
If imageView moves towards right
if(x+iw < deviceWidth)
//Move towards right functionality
If imageView moves towards bottom
if(y+ih < deviceHeight)
//Move towards right functionality
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 programmed a drawing application, I want to retrieve all the X Y of my drawing. That is to say each time I touch the screen, the coordinates x and y I put them in a two dimensional table ,
I made a toast to find out when the coordinates change, and I found that they change in the movetouch method, so I declare a table in the method and I still make a toast to see the 10 line Of my array, the toast changed co-ordination so I understood that in fact values are crushed whenever the x and y change, or I am planting
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
upTouch();
invalidate();
break;
case MotionEvent.ACTION_MOVE:
moveTouche(x, y);
invalidate();
break;
}
return true;
}
Method moveTouch
public void moveTouche (float x,float y ) {
if ((canDraw)&& drawing) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if(dx >= Tolerance || dy >= Tolerance){
path.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
mX = x ;
mY = y;
double[][] point = new double [99][2];
for (int i = 0; i < 99; i++) {
point[i][0]=x;
point[i][1]=y;
}
Toast.makeText(getContext(),"y = "+point[10][1]+" ",Toast.LENGTH_LONG).show();
}}
}
You can read as many points as you want from any path. Example how to read coordinates from the middle of path:
PathMeasure pm = new PathMeasure(myPath, false);
//coordinates will be here
float aCoordinates[] = {0f, 0f};
//get coordinates of the middle point
pm.getPosTan(pm.getLength() * 0.5f, aCoordinates, null);
You can pass any distance from the path start to get point coordinates.
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()?
I am making a simple platform game in Libgdx... in which I have made the player to move left, move right and jump. The code works fine on Desktop but on Android devices, Jump is not fired when the player moves left or right. It looks strange. Here is my code...
private void updatePlayerForUserInput(float deltaTime)
{
// check input and apply to velocity & state
if ((Gdx.input.isKeyPressed(Keys.SPACE) || isTouched(0.87f, 1,0,1f)) && world.player.grounded)
{
world.player.velocity.y += world.player.JUMP_VELOCITY;
world.player.state =2;
world.player.grounded = false;
}
if (Gdx.input.isKeyPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.A) || isTouched(0, 0.1f,0,1f))
{
world.player.velocity.x -=world.player.MAX_VELOCITY;
if (world.player.grounded)
world.player.state =1;
world.player.facesRight = false;
}
if (Gdx.input.isKeyPressed(Keys.RIGHT) || Gdx.input.isKeyPressed(Keys.D) || isTouched(0.2f, 0.3f,0,1f))
{
world.player.velocity.x =world.player.MAX_VELOCITY;
if (world.player.grounded)
world.player.state =1;
world.player.facesRight = true;
}
}
private boolean isTouched(float startX, float endX , float startY, float endY)
{
// check if any finge is touch the area between startX and endX
// startX/endX are given between 0 (left edge of the screen) and 1 (right edge of the screen)
for (int i = 0; i < 2; i++)
{
float x = Gdx.input.getX() / (float) Gdx.graphics.getWidth();
float y = Gdx.input.getY() / (float) Gdx.graphics.getHeight();
if (Gdx.input.isTouched(i) && (x >= startX && x <= endX) && (y>=startY && y<= endY))
{
return true;
}
}
return false;
}
I took the idea from the demo platform game SuperKoalio by mzencher at
https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/superkoalio/SuperKoalio.java
Please suggest
This code:
float x = Gdx.input.getX() / (float) Gdx.graphics.getWidth();
float y = Gdx.input.getY() / (float) Gdx.graphics.getHeight();
Is always getting the x/y from the first active touch. You need to check the "i'th" active touch. Like this:
for (int i = 0; i < 20; i++) {
if (Gdx.input.isTouched(i)) {
float x = Gdx.input.getX(i) / (float) Gdx.graphics.getWidth();
float y = Gdx.input.getY(i) / (float) Gdx.graphics.getHeight();
if ((x >= startX && x <= endX) && (y>=startY && y<= endY)) {
return true;
}
}
return false;
Also, you should probably iterate through all 20 possible touch points, since up to 20 touch points can be tracked by the hardware. (Try putting three fingers in the "jump" region and then add a fourth finger in the "move left" region.)