android dispatchTouchEvent get tapped view - android

I call this function in my activity :
#Override
public boolean dispatchTouchEvent(MotionEvent touchEvent)
That allows me to process action before any components get focused or even deny the focus to these elements.
PROBLEM : I was wondering how I could know what component (View) has been touched in this function, then I could choose if I want to consumme the event or not.
UGLY SOLUTION : I'm currently having an ugly solution which is : I know the position of the component that is allowed to get the event, and I do a plenty of condition to approximately decide if the user clicked on this component.
Thanks.

You probably want to use the OnTouchListener
private OnTouchListener mOnTouchListener= new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId()){
case R.id.id1):
// Do stuff
break;
case R.id.id2:
// Do stuff
break;
}
return false/true;
}
};

view.getid==R.id.//id in layout// condition can be checked for the required view is clicked

Related

Swapping between Listeners in Android

I'm having problems dealing with a button and its two listeners.
My objective is swapping two listeners of a button using it.
It's not the behaviour I need. I need to release the button, and then click it again in a different way (with a different listener).
So.. I "onTouch" this button, and when I release my finger, I need to swap its "onTouch" listener to an "onClick()" one.
Now, I tried to accomplish my goal doing the following:
final View.OnClickListener play_listener = new View.OnClickListener() {
#Override
public void onClick(View v) { Utility.playRecording(mediaPlayer); } };
final View.OnTouchListener rec_listener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
if (Utility.checkPermission(view.getContext())) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Utility.startRecording(recorder, output_formats, currentFormat, file_exts, timer);
break;
case MotionEvent.ACTION_UP:
Utility.stopRecording(recorder, timer);
//disabling my onTouch Listener
recplay_button.setOnTouchListener(null);
//Setting a new listener for the same button
recplay_button.setOnClickListener(play_listener);
//Changing its color.
recplay_button.setBackground(getDrawable(R.drawable.coloranimreverse));
break;
}
} else {
Utility.requestPermission(view.getContext());
} return false; }};
So, the swapping works but I can't get the reason why after setting the onClickListener it also execute it, playing the sound I set in the other listener. Does the MotionEvent.ACTION_UP counts as a click?
Do you know how can I get through this? What I need is just not execute the onClick() listener in the same moment that I set it in the OnTouch() listener.
Thank you all.
Your OnClickListener is firing on ACTION_UP because you're unconditionally returning false from onTouch(). Returning false there tells the View that you've not consumed the event, and that it should handle it, as well. In this case, it means that the View will perform its click handling, and now that it's got an OnClickListener set, that gets called. (In fact, you could've set the OnClickListener from the start, and would've achieved the same behavior.)
Returning true in the ACTION_UP case will signal that you're consuming that event there, so the View won't end up calling its OnClickListener. This might be sufficient for your use case, however, it also means that the View won't perform any of the other state changes it would normally do for ACTION_UP; e.g., changing its Drawables to their not pressed state.
Rather than juggling listeners, and trying to decide which events to consume, and which to pass on, it might be preferable to handle everything in the OnTouchListener, track the current state in some sort of flag variable, and again return false unconditionally in onTouch(). In this way, we're simply "inserting" the desired behavior, and allowing the View to continue handling events and state as it normally would.
For example:
private boolean recordState = true;
final View.OnTouchListener rec_listener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent event) {
if (Utility.checkPermission(view.getContext())) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (recordState) {
Utility.startRecording(recorder, output_formats, currentFormat, file_exts, timer);
}
break;
case MotionEvent.ACTION_UP:
if (recordState) {
recordState = false;
Utility.stopRecording(recorder, timer);
recplay_button.setImageDrawable(getResources().getDrawable(R.drawable.coloranimreverse));
}
else {
Utility.playRecording(mediaPlayer);
}
}
} else {
Utility.requestPermission(view.getContext());
}
return false;
}
};

onTouchListener in Android will detect touch on all parent view

I have
RelativeLayout
A---BIG IMAGE
B---MEDIUM IMAGE
C---SMALL IMAGE
The picture is looking like this
I have used below java code
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (v.getId()) {
// LEFT
case R.id.tblLOne:
System.out.println("IMG_L_A");
playBeep(TABLA_L_BIG);
changeLeftDrum();
break;
case R.id.tblLTwo:
System.out.println("IMG_L_B");
playBeep(TABLA_L_MID);
changeLeftDrum();
break;
case R.id.tblLThree:
System.out.println("IMG_L_C");
playBeep(TABLA_L_SMALL);
changeLeftDrum();
break;
return false;
}
return true;
}
Problem is that whenever I click on small (BLACK) Image
I got following output
IMG_L_A
IMG_L_B
IMG_L_C
Whenever I click on Middle Image I got
IMG_L_A
IMG_L_B
On OuterImage big image
IMG_L_A
Why I am getting it's all behind ImageView's OnTouch Method
It is working perfect with onClick but not with OnTouch
It's because the views are stacked on top of each other.
The important point here is to know the importance of the Boolean flag that you return from your onTouchListener. The boolean flag tells android if the event was consumed or not.
Suppose, you touch tblRthree, the case R.id.tblLThree executes, but then since you return false, it appears to android that the event was not consumed and this event bubbles up to the tblRTwo view which is just behind tblRthree view, which executes the same listener for the case R.id.tblLTwo but then again you return false so, it bubbles up to view tblROne and all three cases execute.
You should return true whenever you consume the event, and false when you don't.
onTouch method will be called in multiple events, all you need is to check whether it is MotionEvent.ACTION_DOWN or not.
So, it will look something like this:
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()!=MotionEvent.ACTION_DOWN)
{
return false;//we are not going to handle it
}
switch (v.getId()) {
// LEFT
case R.id.tblLOne:
System.out.println("IMG_L_A");
playBeep(TABLA_L_BIG);
changeLeftDrum();
break;
case R.id.tblLTwo:
System.out.println("IMG_L_B");
playBeep(TABLA_L_MID);
changeLeftDrum();
break;
case R.id.tblLThree:
System.out.println("IMG_L_C");
playBeep(TABLA_L_SMALL);
changeLeftDrum();
break;
}
return true;//we have handled it
}

How to unsubscribe from onTouch() event

When application is started I run a custom pop-up till a user touches the screen. When screen is touched I catch it with event onTouch() and cancel the pop-up. From this point I don't need the event anymore.
The problem is the event is alive and continues to jump up every time a user touches the screen.
Is there any way to unsubscribe from this event? Something like in c# -= eventName.
The code is below:
#Override
public boolean onTouch(View v, MotionEvent event) {
if (!_stopToast)
{
_hintToast.cancel();
_stopToast = true;
}
return false;
}
There's no such method (lets say removeTouchListener or similar) which will help you to remove an already defined touch listener from a view. Setting null to setOnTouchListener won't help too. What you can do is to create a new object reference of OnTouchListener class which does nothing and set it in setOnTouchListener. For example:
public final OnTouchListener dummyOnTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent rawEvent) {
return false;
}
};
And simply use it as below:
yourView.setOnTouchListener(dummyOnTouchListener);

Class cast exception by onclick listener in android

I have written a code to implement onclick events of buttons in android.
I have written the following line to set the listener in oncreate method.
I want to recognize the touch event of a button in the application.i am getting a class cast exception in android.
mybtn[i].setOnClickListener( (OnClick Lisener)this);
for the alternatives to recognize the ontouch event i have looked at the SetKeylistener() , setonkeylistener() and setontouchlistener() methods. but i am not getting which one to use exactly.
What exactly i want to achieve is TTS should speak the number when the button is touched, and on the key release that number should be added to some textbox. so what methods should i use to accomplish these things.
You should accomplish the effect by doing this:
mybtn[i].setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View arg0, MotionEvent arg1)
{
switch (arg1.getAction())
{
case MotionEvent.ACTION_DOWN:
// Do some stuff
break;
case MotionEvent.ACTION_UP:
// Do some stuff
break;
}
return false;
}
});
use View.OnClickListener if you use setOnClickListener.
To accomplish your purpose you can btn.setOnTouchListener and do something according to the MotionEvent,such as event.getAction=MotionEvent.ACTION_UP ...
for example:
btn.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
}
return false;
}
});
Implement interface in your activity class which ever listener you want to listen on button, like for onClickListener
public class A extends Activity implments OnClickListener

Custom view with button like behavior on click/touch

I have created a custom View which I usually attach an onClickListener to. I'd like to have some button like behavior: if it is pressed, it should alter its appearance which is defined in the onDraw() method. However, this code does not work:
//In my custom View:
#Override
protected void onDraw(Canvas canvas)
{
boolean pressed = isPressed();
//draw depending on the value of pressed
}
//when creating the view:
MyView.setClickable(true);
pressed always has the value false. What's wrong?
Thanks a lot!
hey buddy,your fault is you are not implementing click or touch evnt for ur custom view.thr is no click evnt for view.you can use touch event instead of this:so below code work 4 u:
myView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
break;
}
return true;
}
});
in this code use action_up for click and you get it worked for you
have you considered just using a button to do what you want? you could use ToggleButton and write a short selector in xml that will allow you to specify an image to use when pressed or not. this question may be of some help to you.
To make your new custom button draw on clicks don't forget to invalidate the form as necessary. This is a little gotcha. E.g.
#Override
public boolean onTouch(View v, MotionEvent event)
{
/* Parse Event */
this.invalidate();
return true;
}

Categories

Resources