Android Studio: MotionEvent - touch tracking - android

I'm new to Java but handling it quite well because of my years of programming with python (basic concepts carry from language to language).
I have a practice project set up and the only propose of this project is for me to learn how to do things the java/android studio way, logic wise.
So logically, the last python based api I used, there was a way to issue your own ID to touches and keep track of those touches; therefore you knew if a touch still existed or not.
That's where I am right now. I know how to get the touch ID and then get the Index that holds the touch data. Basically I'm using a For Loop on the motion event to process all touches to the screen.
Here's the thing....
Lets say I have 10 touches to process and what I do in a loop is basically collect the info of the touches and store them in a hashtable, so I can then later process all the touches in the hashtable.
So as I pull a touch data from the hashtable to process, I want to first check to see if the touch still exits. I'm guessing once a touch enters the "UP" state, it goes out of scope after that because a touch is over after release.
Sure I can just check the "Action" to see if it's equal to "UP" but if the touch doesn't exits anymore, that would raise and exception...right?
What I thought about doing was, calling "getPointerCount" again, looping through and getting the IDs again and see if the ID of a touch in my hashtable still exits in the MotionEvent and if the ID exists and the "Action" is still equal to "DOWN", then process the touch. Otherwise, if the ID does not exists or the "ACTION" is equal to "UP", do a release button event if needed or just delete the touch from my hashtable because it doesn't exits anymore.
I can't help but get the feeling of redundancy though when considering that approach.
Is there a way or method I don't know about that allows you to check if a touch still exits before you process actions relating to it?
I was thinking just now.... Well, kind of guessing that, if you have five touches that hit the screen and one of the touches triggers the opening of a menu and that button had higher priority over the other four touches, you could simply ignore the other for touches for that frame and open the menu and in the next frame of the app, if the other four touches are still down, you can deal with them then accoring to their priority..... But then again, the touch could still exists in the next frame but the "Action" may be "UP" or "MOVE" instead of down, thus allowing one to write code for a release or move event. With this thought, storing touch data in a hashtable is really not needed then, granted a touch this is on action "UP" will go out of scope in the very next frame (I'm guessing).
......hum......
Maybe I'm just over thinking it.
Forgive any "typos", eyes are that super any more.

The code I wrote was correct but I wasn't getting the results because I was using MotionEvent.getAction().
For anyone new to Android Studio and its APIs, do not use MotionEvent.getAction(). Instead, use MotionEvent.getActionMasked()...otherwise, multi-touch will not work correctly.
For me, only the 1st touch was registering when I was doing a double button press test. I thought my code was flawd but all was working correctly when I used MotionEvent.getActionMasked().
Turns out, MotionEvent.getAction() just doesn't return an Action...other data is attached to it, which throws off your code.
MotionEvent.getActionMasked() returns the Action only.

Related

Prevent touch within small time interval in Android

I am facing an issue if user touches multiple button within a small time interval(less than 1 second). I want only one of them to be executed. Similar issue with touch and swipe as well.
I have tried below solutions:
Use a boolean flag and set inside onClickListener. If this flag is then directly return from onClickListener. This approach does not work for me as it is not very deterministic to decide correct place to unset the flag.
Check time difference between two consecutive onClicListener and ignore 2nd if it is less than some threshold value. Issue with this approach that it is not very deterministic and threshold may vary for devices. Also if I keep it very high and device will appear to be very slow.
What I want is 2nd touch to not even register if first touch onClickListener is not completed. Are there other ways to control the touch events in Android?
What you're looking for is a debouncer / debounced click listener. You can find implementation details by searching using these terms, with some examples here - https://medium.com/swlh/android-click-debounce-80b3f2e638f3 - and here - Avoid button multiple rapid clicks.

Passing clicks events from floating app to covered app

I have a floating app which works perfectly.
I am using OnTouchListener to catch events since I need to use the GestureDetector for swipes etc.
My only problem is that sometimes I wish to ignore certain events on the view.
In this case the view is invisible but not "gone" because I need it to accept certain gestures but not others.
I can't seem to be able to do that.
Returning false from "onTouch" simply doesn't work.
I checked that by experiment by disabling the GestureDetector and simply always returning false just to see what would happen. Result was nothing going through.
Is it even possible to pass a click through to a covered app?
Due to security reasons it's not possible to record and pass a click below (essentially allows building a keylogger).
Best you can do is have your floating window small enough to start the touch but not cover too much of the screen below.

How can I suggest a swipe-to-right gesture in a list on a mobile device?

I have done live user testing for a list in my app, and have come to an interesting puzzle.
A list, specifically a single-column table in iOS, may often have a swipe right gesture for more actions, like the twitter app and mail app, and a million other apps. But when important functionality is embedded in the UI beyond that action, and a user cannot figure it out, the only thing that comes to mind to alleviate that is something like the accessory button, ie. a right-pointing triangle or chevron button.
There is probably another way but it's not coming to me. Maybe making the rows taller than normal?
This was meant as a comment but was rejected as too-long.
So after thinking more about this, the ideal solution is a visual clue, rather than painfully obvious text saying "swipe a row for more options". Perhaps when a list (UITableView, etc) is shown and rows (UITableViewCell, etc) are created and added, then as they appear an animation begins of the main visible content sliding into place in the OPPOSITE direction of the desired swipe animation, with a minimal visual indicator afterward, reminding the user that the content is moveable!
Sound good? Optionally, immediately before the animation begins, any underlying content may be shown for a split second (if its supposed to appear underneath). Sweet!

Android - touch two buttons at same time

What is the best way to touch two buttons at the same time? I am working on an app that has buttons, like a D-pad and a jump button, to move your character around. Right now I am just using normal buttons and handling them with an OnClickListener. I am having problems when I am running and need to jump at the same time, or if I am running to the right, then want to go left without having to pick my finger up. I know this is possible because it works greats on game like Sonic CD and some others. Any help would be greatly appreciated.
OnClick fires only on release. Instead use the touch event handlers so that when they touch occurs, you get the events. However, note that not all devices have multitouch, and thus not all of them will be able to handle the double-touch case correctly. They will provide touch events, but not two of them. Also note that you may receive multiple "pointers" within a touch event, and will have to decide which is "yours" for each button if that matters.

Touch more one button at once

Hello i make appliction like Drum Studio. I need make support for touch more one button at once. For example: User touch button1(AND HOLD IT!) it play sound, but user still hold its, user click another button and it play sound too. How make it programmatically? By default onTouch or onClick use, if 1 button pressed, another buttons not react before button isn't released.
Use the onKeyDown() events to trigger each response and onKeyUp() events to finish them.
http://developer.android.com/reference/android/view/KeyEvent.html
http://developer.android.com/reference/android/view/KeyEvent.Callback.html
For touchs, you can use the OnTouchListener
http://developer.android.com/reference/android/view/View.OnTouchListener.html
and determine the kind of touch by the MotionEvent:
http://developer.android.com/reference/android/view/MotionEvent.html
To clarify my response: To make a sound while holding one button, you can start the sound when the ACTION_DOWN action in the MotionEvent event is triggered and stop it with the ACTION_UP action of the same event.
Create a class extending View where you're holding all your buttons.
Override the onTouchEvent vor that class.
Switch between the different actions.
Use event.getX() and event.getY() to figure out where the touch event was originated.
Check which button is located at that position
Play the sound accordingly.
You cannot touch two separate Views at the same time, even if multi-touch is supported on your device. If you touch Button1 first, all subsequent MotionEvents (including ones with separate pointer IDs) are bound to that View.
Unless you're using a dedicated game engine like AndEngine that has this sort of functionality built in, your only option is to capture all the MotionEvents yourself (most easily with an empty ImageView covering your entire screen) and route them to the appropriate Views based on their screen coordinates. This can get tricky, especially with multiple touch pointers, but the Android UI framework does not natively support the kind of multi-touch you require.
You definitely want to be using Android 2.0 or higher - previous versions don't support multitouch.
Check the pid in your onTouch - 0 is a single touch, 1 is the second.

Categories

Resources