Android Event Propagation - android

The Android input event documentation here seems to imply that returning false in an event listener will cause the event to continue on to other listeners. For example
OnTouchListener touchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// should continue on to other views
return false;
}
};
The problem is if I have two buttons in the same layout and I click on one I would expect the event to continue on to all views since I'm returning false, for example:
Button submitButton = (Button) findViewById(R.id.submit_button);
submitButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("--> submitButton");
return false;
}
});
Button clearButton = (Button) findViewById(R.id.clear_button);
clearButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
System.out.println("--> clearButton");
return false;
}
});
Since the submit button's listener returns false I would expect the click result to be sent on to the clear button but the output is always:
--> submitButton
--> submitButton
Can someone explain how events are propagated within a view since I seem to be misunderstanding the article?

The events are propagated from the parent views to the child views. Never to sibling views.
What you are trying would work if your clearButton were inside the submitButton (witch is not even possible).
You could mimic that behaviour with performClick()

Related

Android: where is View.getOnTouchListener()?

I would like to implement a generic system that overrides all the onTouchListener
on a viewGroup and restore them later.
I tought about map to store each view's original listeners but I did not find any way to
get the currently assigned listener.
I need to do something like this:
View v;
View.onTouchListener backupListener = v.getOnTouchListener();
But unfortunately getOnTouchListener does not exists ? How can I do ?
if you use setOnTouchListener it's not overriding the touch Listener but just saving a pointer to another touch listener, so you can actually call to the original touch Listener:
view = findViewById(R.id.someView);
//alternative:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("touch"," alternative");
return true;
}
});
//call to the original:
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return v.onTouchEvent(event);
}
});
you can check out the source code of setOnTouchListener();

Keep pressed a button in onClick()

I want to keep a button displayed pressed. I want to use another way instead of onPressed() in onTouch(). I add setPressed(), setSelected() but not worked. when i add these methods in onTouch() the program is good but my animation is very slow.
Can i use these method in onClick() method but works in this?
Please explain for me
Instead of using the onClick-event which returns the button to the non-pressed state, you can set the pressed state in the onTouch-event:
yourbutton.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
((Button) v).setPressed(true);
//TODO: Add the code of your onClick-event here
}
return true;//Return true, so there will be no onClick-event
}
});
If this affects any animation, you should look for the problems there.
This piece of code makes the button work as a toggle button. It sets the pressed property to its opposite.
If the button is pressed, it's set as unpressed.
If the button is unpressed, it's set as pressed.
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Button b = ((Button) v);
b.setPressed(!b.isPressed());//if pressed, unpress; if unpressed, press
}
return true;
}
What you are describing seems to be a toggle button. Maybe you should check this out, instead of doing a hackish solution :
Toggle Buttons
Extend ToggleButton or:
Button button = (Button) view.findViewById(R.id.button1);
button.setTag(false);
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP)
if ((boolean) v.getTag()) {
v.setPressed(false);
v.setTag(false);
return false;
} else {
v.setPressed(true);
v.setTag(true);
return true;
}
return false;
}
});

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);

Android turning clicks into touches

I have an on click listener:
whiteKeyPressedArray[i].setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}}
I see that this allows touches:
public boolean onTouch(View v, MotionEvent event) {
//Switch case for type of touch
}
But how can I detect touch rather than click on my whiteKeyPressedArray[i]?
Thanks!
OnTouch will fire many many times :), actually onTouch will be trigered over and over again as long as you keep your finger to that element (as long as you touch that element). Where onClick will be fire just ones but ONLY if you return false from your onTouch handler.
I don't know what the whiteKeyPressedArray[i] is, but have you tried:
whiteKeyPressedArray[i].setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return true; // or false if you want the event to pass on
}
});
Maybe this is what you are looking for?

Is there anyway to remove an onTouchListener from a view object?

I have an on touch listener for a webview, but it has a bad effect on the functionality of the webview, so I am wondering if there is anyway to removed the on touch listener after the initial interaction?
webView.setOnTouchListener(null);
So in you activity you would set your overridden onTouchListener:
mWebView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.setOnTouchListener(mWebView.mOnTouchListener);
return false;
}
});
And you would have to make a new class, extending WebView. And within it you would define an OnTouchListener.
public final OnTouchListener mOnTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent rawEvent) {
return false;
}
};
Setting the ontouchlistener to null doesn't reset it to the default definition. You still have to provide an actual listener.
I was looking for help online and got to this post.
When I did
myView.setOnTouchListener(null);
my myView stopped responding to the onTouch.

Categories

Resources