I am havig troubles counting how much touches are being made in each "half" of the screen.
When I touch in the upper side it counts correctly, and the same with the lower side. BUT, when I touch the upper side, dont release it, and touch the lower side, then it counts the wrong side, what is wrong in my implementation?
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_DOWN) {
if(event.getY()<400)
{
}
else
{
}
}
if (action == MotionEvent.ACTION_UP) {
if(event.getY()<400)
{
zenbat=zenbat+1;
tv.setText(String.valueOf(zenbat));
}
if(event.getY()>400)
{
zenbat1=zenbat1+1;
tv1.setText(String.valueOf(zenbat1));
}
}
if (action == MotionEvent.ACTION_POINTER_DOWN) {
if(event.getY()<400)
{
}
else
{
}
}
if (action == MotionEvent.ACTION_POINTER_UP) {
if(event.getY()<400)
{
zenbat=zenbat+1;
tv.setText(String.valueOf(zenbat));
}
if(event.getY()>400)
{
zenbat1=zenbat1+1;
tv1.setText(String.valueOf(zenbat1));
}
}
return true;
}
});
If you want to correctly handle multitouch events you need to use the pointer index to correctly identify the finger generating the event.
I've answered a similar question in Android multi-touch interference where I posted a code example how to do it.
To correctly identify the finger, you should refer to the fingerId in the code posted.
Regards.
Related
I am developing an app for Android Wear and are using the hardware buttons.
I can manage to catch the buttons with the onKeyDown override:
public boolean onKeyDown(int keyCode, KeyEvent event){
Log.i("CLICK", Integer.toString(keyCode));
if (event.getRepeatCount() == 0) {
if (keyCode == KeyEvent.KEYCODE_STEM_1) {
// Do stuff
return true;
} else if (keyCode == KeyEvent.KEYCODE_STEM_2) {
// Do stuff
return true;
} else if (keyCode == KeyEvent.KEYCODE_STEM_3) {
// Do stuff
return true;
}
}
return super.onKeyDown(keyCode, event);
}
I would also like to catch a click on the middle (rotary) button,
but when I click this button, the watch is going back to the default 'home'(watchface)-screen,
and no event is being logged.
I can manage to catch the rotary scrolling, but it's the click I'd like to use.
#Override
public boolean onGenericMotionEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_SCROLL && RotaryEncoder.isFromRotaryEncoder(ev)) {
// // Note that we negate the delta value here in order to get the right scroll direction.
// float delta = -RotaryEncoder.getRotaryAxisValue(ev)
// * RotaryEncoder.getScaledScrollFactor(getContext());
// scrollBy(0, Math.round(delta));
return true;
}
return super.onGenericMotionEvent(ev);
}
Is this possible, or is it impossible to override the functionallity of the middle watch button?
AFAIU It should be getting KEYCODE_HOME as key event on pressing RSB in onKeyDown().
If it is the case then it is controlled by Android framework only and apps can't do anything with it.
Here is the official description
Key code constant: Home key. This key is handled by the framework and
is never delivered to applications.
https://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_HOME
I am trying to make an Android application with two seekbars that can be controlled at the same time (multi-touch). The full source code can be found here
The app is a robot controller, each seekbar controls a motor so to move forward you slide both bars up and so on (speed is controlled by how far you push it up or down) where 50 is the stop state, 100 is the maximum speed forward and 0 is maximum speed backward.
What I am trying to implement is that after you let go of the seekbar it will go back to the stop state (progress 50), however, even though the value is actually set to 50 (using setProgress) but the view won't update to reflect that.
I tried using .invalidate(), .requestLayout() and some old solutions here and here but couldn't get it to work.
Here are parts of the code: (for full code check the github link above)
public class MainActivity extends ActionBarActivity {
...
...
public static void ResetSeekBar(View v) {
if ( v.getId() == R.id.sb1) {
Log.d("before", "Progress = " + Integer.toString(sb1.getProgress()));
sb1.setProgress(50);
Log.d("after", "Progress = " + Integer.toString(sb1.getProgress()));
sb1.invalidate();
//sb1.requestLayout();
} else if ( v.getId() == R.id.sb2) {
sb2.setProgress(50);
}
}
}
public class MySeekBar extends SeekBar {
public MySeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public boolean onTouchEvent(final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("tag", "UP");
MainActivity.ResetSeekBar(this);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.d("tag", Integer.toString(getProgress()));
MainActivity.UpdateText(this, Integer.toString(getProgress()));
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("tag", "DOWN ");
MainActivity.UpdateText(this, Integer.toString(getProgress()));
}
return super.onTouchEvent(event);
}
}
Using a regular button onClick works and do update the view but not after MotionEvent up. So what am I doing wrong?
Also how can I make it reset to 50 but with a fast transition instead of suddenly jumping to the middle?
Of course the solution comes after you ask poeple! anyways, it is much simpler than I thought.
super.onTouchEvent(event) should be called before processing the event, i think I was trying to change it before it actually processed the change, so it was overriding what i did! (not sure just guessing based on the behaviour that I saw)
and here is the function after the fix:
public boolean onTouchEvent(final MotionEvent event) {
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("tag", "UP");
MainActivity.ResetSeekBar(this);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.d("tag", Integer.toString(getProgress()));
MainActivity.UpdateText(this, Integer.toString(getProgress()));
} else if (event.getAction() == MotionEvent.ACTION_DOWN) {
Log.d("tag", "DOWN ");
MainActivity.UpdateText(this, Integer.toString(getProgress()));
}
return true;
}
I am currently trying to detect an ongoing touch event in my Android app.
In detail I want to recognize within a fragment whether the user touches any part of the app's screen.
Android's OnTouchListener works as expected except if the touch event lasts longer than a few seconds without moving.
For example the first 1-2 seconds of touch are being detected but everything after won't.
Is there something like an "OnPressListener" or a workaround?
If it's a well defined gesture you are trying to detect, have a look at GestureDetector.
http://developer.android.com/reference/android/view/GestureDetector.html
You can use
aButton.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View arg0) {
Toast.makeText(getApplicationContext(), "Long Clicked " ,
Toast.LENGTH_SHORT).show();
return true; // <- set to true
}
});
on your aButton and if you are using API < 19 you have to add
android:longClickable="true"
Attribute to your aButton in layout xml.
I finally found it out.
The solution is to use a simple OnTouchListener:
private boolean pressed = false;
#Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
pressed = true;
} else if ((action == MotionEvent.ACTION_UP)
|| (action == MotionEvent.ACTION_CANCEL)) {
pressed = false;
}
return true;
}
I want to detect bluetooth mouse wheel changes,and I know what's the actionCode for mouse wheel changes,but don't know it's being up or down.
public boolean onGenericMotion(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_SCROLL) {
//how to detect mouse wheel being up or down?
}
return false;
}
Thanks very much!
I think the answer can be found in this question: How can my view respond to a mousewheel?
I have copied the code sample from there:
#Override
public boolean onGenericMotionEvent(MotionEvent event) {
if (0 != (event.getSource() & InputDevice.SOURCE_CLASS_POINTER)) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f)
selectNext()
else
selectPrev();
return true;
}
}
return super.onGenericMotionEvent(event);
}
I have a button widget. I want to play sound when the button is pressed and when the user releases the button (takes his finger off the button) the audio playback should be stopped. I have used the following code but it doesn't work.
public boolean onTouch(View v, MotionEvent me) {
int action = me.getAction();
if(action == MotionEvent.ACTION_DOWN) {
playSound();
} else if (action == MotionEvent.ACTION_UP) {
stopSound();
}
return false;
}
Is stopSound() being called? I think you need to return true in the action == MotionEvent.ACTION_DOWN block to tell the system that you handled the event.