android why swipe on a textview will trigger onclick event? - android

I am using the default project template from Android Studio. When I swipe on the textView, the onClick event will get triggered. Is it the designed behavior or where did I do something wrong?

In my experience OnClick is triggered because when you put your finger on textView its ACTION_DOWN method gets called internally and after swipe when you remove your finger its ACTION_UP method gets called internally. So whenever these two combination gets called it calls the onClick method. So when you touch (ACTION_DOWN) the textView and swipe left/right and move your finger outside (without the ACTION_UP event) it won't get called because its ACTION_UP is not called.
PS. This is not the official definition/working of onClick... This is how it worked in my experience.

my solution is extending the parent viewgroup and examining motionevent in the onInterceptTouchEvent.

Related

Android OnTouchEvent and onclick event

I am developing an app, which contains several fragments just like the picture below:
Picture 1
The bottom view is MainActivity, and there are several fragments above MainActivity, which may contain buttons. I want to add a fragment on top in order to listen the OnTouchEvents (gestures), but ignore the onclick events and pass the onclick events to the fragments below.
Here are my questions,
How can I distinguish onTouchEvent and onclick events in my codes?
How can I pass the onclick events to the fragments below?
I saw some people suggested to use onInterceptTouchEvent(), but I am not sure if this applies to my case and I do not really understand how to use onInterceptTouchEvent().
Update:
I tried to override boolean dispatchTouchEvent(MotionEvent ev) to make the top fragment ignore the click event, however since the first touch event must be MotionEvent.ACTION_DOWN, it seems that there is no way for me to determine whether the touch event is click.
So, is there any other way to do this?
From the Documentation
The onInterceptTouchEvent() method is called whenever a touch event is detected on the surface of a ViewGroup, including on the surface of its children. If onInterceptTouchEvent() returns true, the MotionEvent is intercepted, meaning it will be not be passed on to the child, but rather to the onTouchEvent() method of the parent.
The onInterceptTouchEvent() method gives a parent the chance to see any touch event before its children do. If you return true from onInterceptTouchEvent(), the child view that was previously handling touch events receives an ACTION_CANCEL, and the events from that point forward are sent to the parent's onTouchEvent() method for the usual handling. onInterceptTouchEvent() can also return false and simply spy on events as they travel down the view hierarchy to their usual targets, which will handle the events with their own onTouchEvent().
So, you'll have to return true/false (in onInterceptTouchEvent method) according to your application flow logic. If you use OnTouchListener you can avoid using OnClickListener. See example in the documentation to understand it better.
This will give you the idea how onTouch and onClick are different.
You can use custom interfaces to pass data to lower fragment for manipulation

onClick listener drag consideration

Why is the android onclick listener for any views which we listen using setOnClickListener() is not working as expected, I mean onclick similar to desktop mouse event, onclick should be fired when mouse DOWN and UP events are triggered at the same location, but in case of android, after ACTION_DOWN if I move a little and release touch, I still get onclick fired. This is causing some unwanted effect on my TextView, which has links.
Is it because there will be always slightest difference in up and down coordinates? the reason for poor implementation.
USE CASE
Suppose in onclick I need to toggle ActionBar visibility but I do not want that to happen when I swipe which again fire onclick. For I was hoping for a clean code using android inbuilt options instead of using flags around touch listeners.
The onClick method is called on the release (ACTION_UP).
If you want to track the DOWN and UP actions yourself you can use an onTouchListener instead (see http://developer.android.com/reference/android/view/View.OnTouchListener.html).

View.setClickable(false) but ACTION_DOWN events fired

I am trying to understand what clickable in Android means. I have a simple Button subclass which overrides onTouchEvent() and also implements OnTouchListener.onTouch() (returns false to let the event bubble up to the view) and I noticed that the callbacks are called with MotionEvent.ACTION_DOWN (listener first, the view method later), and nothing more. I thought clickable = false disables touch events completely, but apparently not. What does it really do? How can I make sure the view doesn't get any touch events at all (setEnabled(false) seems not to work at all, events for ACTION_DOWN, _MOVE and _UP are fired unhindered).
Why are some touch events handled and other are not for clickable = false? I find it pretty surprising behavior and inconsistent - I would expect MotionEvent.ACTION_UP to be fired as well, but maybe click listeners should not be called. Any guidance?
Update With setEnabled(false) only the View.onTouchEvent method is called, the listener is ignored. Even stranger...
As I understand, setClickable is for calling the onClickListener when you click on it, and the actions like ACTION_DOWN, ACTION_MOVE, ACTION_UP are for handling finger events on the View within a OnTouchListener.

How to add touch event for a Layout that contains a ScrollView

The problem is the the scrolling will intercept with touch event has set to the parent layout.
Can I keep the onTouch event with the scroll in ScrollView ?
This is a very tricky part. There is an overriden method from Activity which is: public boolean onTouchEvent(MotionEvent event)
This is the general method that interprets all the touch events from the whole screen. And you could say, "ok, I can implement this and I am good to go..". And here comes the difficult part on how android works.
As you know every View has its own onTouchEvent() method that you could implement in order to add some custom implementation. So which method will listen? The ScrollView or the Activity? It appears that these touch events go from the "inside" elements to the "outside" elements. I mean parent-child relations.
Another thing to take into account is that the onTouchEvent method returns a boolean. This boolean parameter determines whether the touch event should go one level up or it is handled by the current View. Meaning that if you have a CustomViewA that implements the onTouchEvent() and CustomViewB implementing its own touch event, and the A is a child in B then the touch event would go through A first and if it is not handled it would go to B.
So basically yes it could be done. It depends on what touch event you wanted to do.
So in our case, the ScrollView returns true when the touch events are a horizontal. The activity's touch event will be handled only if the ScrollView touch event is not handled by itself then you are fine. Otherwise you have to override and implement the on touch event of scroll view and in some cases you have to return false so as for the whole layout to implement it. Good luck with the last part. I started to implement a fling effect but came up with some difficulties so I have implemented a 2 finger move with scroll view in it and it works like a charm.
This is about a week of research and experimenting and it is an overview of what I came up with. if you find anything else please let me know. Hope it helped.

touchlisteners and textviews

Actually I'm trying to implement an ontouchlistener into my android (1.5) application.
therefore i implemented the "ontouchlistener" into the class, and then i put my code into the:
public boolean onTouchEvent (MotionEvent e){
//code
}
The problem is, that if I am dragging over an (e.g.) Spinner or EditTextView than this Method isn't called. The only way to solve this which i figured out is to add an ontouchlistener to each of this views manually:
((Spinner)(findViewById(R.id.spinner1))).setOnTouchListener(tl);
((Spinner)(findViewById(R.id.spinner2))).setOnTouchListener(tl);
(tl is the ontouchlistener)
So isn't there a way to catch the touch event before it gets to each of those views?
thanks in advance
Ripei
What exactly do you want to do - do you want to:
Detect whole gestures in some
Activity.
Detect touches only for a given
View
If you want the former:
Take a look at this example:
Fling gesture detection on grid layout.
Basically, you redirect all registered touch events to a GestureDetector.
It understands what exactly is the user input (single tap, double tap, scroll, etc.) and calls the corresponding callback in a SimpleOnGestureListener, which you should implement.
If you want the latter:
You can either:
Override the View's onTouchEvent().
Implement and hook onTouchListener (if you want to get the touch before it's dispatched to it).
If you want to implement onTouchListener, you'll be doing your work not in the onTouchEvent() method, but in the interface's onTouch() method.
Hope that helps.

Categories

Resources