In my DynamicListView class, I need to handle two events: onTouchEvent and OnItemLongClick event. My expectation is that the onTouchEvent is called before the OnItemLongClick event. However, this is not the case. The OnItemLongClick event is handled without any call to the OnTouchEvent. Is there anyway to specify the order of these handlers ? I need to get the coordinates of the touch event first before handling the OnItemLongClick event.
Try to override dispatchTouchEvent(MotionEvent ev) in your DynamicListView.
Related
The user can draw over view (with a pencil) and i want a listener to know if the user was drawn over other views. When the user is drawing over a view, i want to change the view's color.
I tried with OnTouchListener, OnHoverListener, OnFocusChangeListener i also tried to override the method onTouchEvent, but none of these were called.
Screenshot of the sample:
http://imgur.com/u3tkwRN
You should handle onTouchListener by calling ViewObject.setOnTouchListener the OnTouchListener passes to argument . The first is the Calling View and the second is a MotionEvent object . The motion event has a getAction() method than returns a integer you should write a if statement and check whether the getAction() value equals to MotionEvent.ACTION_DOWN . In the block of the if statement write your code . Also you can handle unhover event by write another if statement and check whether the getAction() integer equals to MotionEvent.ACTION_UP and write another code in if block statement . Your problem will be solved completely.
I have a simple layout:
<CustomFrameLayout>
<ListView />
</CustomFrameLayout>
In my CustomFrameLayout, I am overriding:
onInterceptTouchEvent(MotionEvent event);
and returning false. When scrolling the ListView, the onInterceptTouchEvent receives the ACTION_DOWN and the first ACTION_MOVE event. Then, the ListView seems to take over and onInterceptTouchEvent fails to receive the following ACTION_MOVE events.
This goes against what the documentation states:
For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().
http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)
I have looked into requesting touch events to not be intercepted at the ListView level.
requestDisallowInterceptTouchEvent(boolean disallowIntercept)
This does not seem to have any effect. Should I be calling this on the ListView cell view's as well? Is there something else I am missing? I am testing on Android 4.4
Thanks.
you should return true in onInterceptTouchEvent(MotionEvent event);
true indicates that you are willing to receive further touch actions where as false indicates you are not interested further actions...
I have decided to override this method instead. Here, I can guarantee that I can intercept all touch events before they are dispatched to and potentially consumed by the child views.
dispatchTouchEvents(MotionEvent event);
I want my callback to be fired on every touch event for a particular view. I've found similar question: View.onTouchEvent only registers ACTION_DOWN event by there is no direct answer.
If true is returned from onTouch() then further events belonging to the same touch (eg. ACTION_MOVE) are reported, but flow is disrupted and normal event processing does not happen (eg. View is not entering in pressed state).
If false or super.onTouchEvent is returned then only ACTION_DOWN is reported but not other actions and normal processing happens correctly (eg. View is entering in pressed state). Unfortunately other callbacks like onInterceptTouchEvent() aren't called as well.
I want to be both notified on all touch events (ACTION_DOWN, ACTION_MOVE and so on) and not disrupt normal processing (eg. View should enter correct state when touched). How to achieve this behavior?
You can try to extend your particular View and overwrite dispatchTouchEvent like this
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
handleTouch(ev);
return super.dispatchTouchEvent(ev);
}
And implement handleTouch to do whatever you want to do without disrupting the normal flow.
ths sdk said:
3、For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().
4、If you return true from here, you will not receive any following events: the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to your onTouchEvent() method and no longer appear here.
But when i use this method,no matter what onInterceptTouchEvent() returns ,it does the same work! And never did MotionEvent.ACTION_MOVE or MotionEvent.ACTION_UP been captured by this method. Can anybody help me figure it out?
ths!
Normally the touch goes from most upper view to the lowest through onInterceptTouchEvent and then it goes back via onTouchEvent.
If you return true in onInterceptTouchEvent you forbid it to continue and the view where you returned true is the last one to receive the touch, you consume it
You can also disallow your parent view to consume the event by
requestDisallowInterceptTouchEvent(true);
When none of the children of your view return true in onTouchEvent, onInterceptTouchEvent will ONLY be called for MotionEvent.ACTION_DOWN.
Here is a complete description of the MotionEvent processing.
I want to listen to touch events for a viewFlipper. I've been able to listen to touch events in my activity and then modify the viewFlipper but these events are fired wherever the user is within the activity and I need to capture touch events specifically on the viewFlipper. I have tried adding setOnTouchListener but it is not called. I'm assuming the viewFlippers children (webviews) are 'consuming' the touch events.
One solution would be to setOnTouchListener's to each of the webviews but this feels like a hack. Does anyone know another way?
Thanks,
Ian
Sorry if this is a double post - but my previous post seems to have vanished.
Use ViewGroup.onInterceptTouchEvent(MotionEvent)
You should Reference the Android Documentation as it's usage is quite complicated.
Basic Summary of use:
You receive the touch event here. If you want to consume it, return true and control will be passed to the ViewFlipper's onTouchEvent(). Return false and it will continue to be passed to the child. onTouchEvent() should also return true to ensure all further events are returned to the ViewFlipper's method. The child will also receive the original event with the action ACTION_CANCEL.
Finally It worked for me. Return true by default to get multiple calls on this listener.
viewFlipper.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (this.gestureDetector.onTouchEvent(event)) {
return false;
}
return true;
}
});
I was having the same problem and found your page trying to google for an answer.
After a few very frustrating attempts I ended up finding a quite easy solution, I'm still listening to the touch on the whole activity just like you did, but on the OnTouchEvent I filter if the ViewFlippers is touched or not:
#Override
public boolean onTouchEvent(MotionEvent event) {
if(mFlip.isInTouchMode()){
return gestureDetector.onTouchEvent(event);
} else{
return super.onTouchEvent(event);
}
}
hope it helps!