Index

Android apps - Dragging

See AndroidStudio on drag and drop.

I am starting to investigate this.

Please note that this is the primitive way of doing dragging, etc. For higher levels of Android (level 3.0 + ) there are more sophisticated ways of doing stuff. But I'm trying to make everying API 8 (Froyo), which is level 2.2. That means it runs on a lot of stuff, but is more primitive. Suits me!

Finding x and y
Detecting touch in a view
Touch inside a grid

Finding x and y

Put this method in app/java/com.(the project name)/MainActivity, after onCreate, for example.

public boolean onTouchEvent(MotionEvent ev) { final int action = MotionEventCompat.getActionMasked(ev); if (action==MotionEvent.ACTION_DOWN) { float x = ev.getRawX(); float y = ev.getRawY(); // This is the x,y position on the whole screen where your finger first touches // You might want to save these values } else if (action==MotionEvent.ACTION_MOVE) { float x = ev.getRawX(); float y = ev.getRawY(); // This is the x,y position on the whole screen where your finger moves. // It is constantly changing // You might want to put code in here to action something during the move so people can see it } else if (action==MotionEvent.ACTION_UP) { float x = ev.getRawX(); float y = ev.getRawY(); // This is the x,y position on the whole screen where your finger lifts up. // If you put code here, it won't get done until the finger is lifted, which might confuse the user } return true; }

You can test for other "action==", such as "MotionEvent.ACTION_POINTER_DOWN", "MotionEvent.ACTION_POINTER_INDEX_SHIFT", "MotionEvent.ACTION_POINTER_UP". I gather these are connected with if you put a second finger on the screen at the same time as the first. There is a "MotionEvent.ACTION_CANCEL" as well.

If you put a second finger down, it seems to get ignored with the above code, unless you left the first finger, in which case the second finger takes over. There is some code in AndroidStudio to stop this, but it doesn't worry me much.

Android Studio also uses the following for getting x and y. However, this gives a different origin to that used below, which is why I've used the 'raw' values above.

final float x = MotionEventCompat.getX(ev, pointerIndex); final float y = MotionEventCompat.getY(ev, pointerIndex);

Detecting touch in a view

It's not much good finding out where the touch is if you don't know how relevant it is to what's on the screen! You need to find out where a view (such as an image or a grid) is on the screen as well. This involves finding out the x & y co-ordinates of the top left-hand corner of the view, and also how wide and high the view is.

You will need to define the view in app/res/layout/activity_main.xml - the code below is for an image view called "starPix".

Define as a global variable (before the Oncreate method):

public static int [] xy = new int [2]; public static int w; public static int h;

Inside the code for "action==MotionEvent.ACTION_DOWN":

ImageView starV = (ImageView) findViewById(R.id.starPix); starV.getLocationInWindow(xy); w = starV.getWidth(); h = starV.getWidth();

The width is now in "w", the height in "h" and the x and y co-ordinates of the top left hand corner is in the array xy[]. You can now test, in "action==MotionEvent.ACTION_DOWN" or "_MOVE" or "_UP" as follows:

if (x>xy[0] && x<(xy[0]+w) && y>xy[1] && y<(xy[1]+h)) { // the code for when the finger is inside this view }

Touch inside a grid

You need to code some extra stuff for grids, since otherwise touch doesn't seem to work. This seems to work OK:

The "public class MainActivity" statement (at top of app/java/com.(the project name)/MainActivity) as follows:

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {

In the "onCreate" method, code:

gridV.setOnTouchListener(this);

Add an extra method:

public boolean onTouch(View v, MotionEvent event) { onTouchEvent(event); return true; }

You find the x and y co-ordinates of the touch as above. You can also find the x & y co-ordinates for the top left hand corner of the view. The code below finds these co-ordinates for the whole grid view, and calculates where the touch is within this. (I tried to do it for the element views inside, but couldn't get it to work!)

if (action==MotionEvent.ACTION_DOWN) { float x = ev.getRawX(); float y = ev.getRawY(); findSub (x, y) } public int findSub (float x, float y) { GridView gridV = (GridView) findViewById(R.id.gridView); gridV.getLocationInWindow(xy); int width = gridV.getWidth(); int x2 = (int) (x-xy[0]); int y2 = (int) (y-xy[1]); x2 = x2 / width; y2 = y2 / width; int sub = y2 * cols + x2; if (sub<0 || sub>=newOrder.length) {sub=-1;} return sub;

Making "findSub" a method means that you can call it during ACTION_DOWN, ACTION_MOVE or ACTION_UP, as you please.



© Jo Edkins 2016 - Index to Android app index