my on Touch() method never gets called, even if I touch the screen, do you know why?
#Override
public boolean onTouch(View arg0, MotionEvent ev) {
Log.v("drawing", "Touched");
return true;
}
and here the class
public class Run extends Activity implements Drawer, OnTouchListener{
Currently in your code u didn't set any setOnTouchListener to any view or layout.
for example, your touch method has to work on, add the setOnTouchListener for ur xml layout in ur code.
AbsoluteLayout mainLayout // i'm using absolute layout in xml , change according to ur xml main layout
mainLayout = (AbsoluteLayout) findViewById(R.id.container);//reffer the id
mainLayout.setOnTouchListener(this);//set listener
now touch the screen and check the log ..
onTouch in Activity will almost never be called, except if none of the Views consume the touch event.
Instead, if you really want your Activity to handle touch events, listen for touch events in onInterceptTouchEvent(MotionEvent).
An interesting talk on this: Mastering the Android touch system.
Related
From the Event Handling Framework of android I find that this is its mechanism:
Event get catch if the user interacts with the device screen
It is stored in a MotionEvent Object.
Android gives this Object to the Activity dispatchTouchEvent() method.
This method dispatch event to the listener of activity . if they did not consume it, it go to the biggest parent of activity, for example, linear layout.
And this mechanism that every dispatch method, dispatch MotionEvent to the listener of view and if those did not consume it to a child of view.
After this MotionEvent object reaches the last view in the hierarchy it goes up in the OnTouchEvent() method of child and goes higher to OnTouchEvent() of a parent till it reaches to OnTouchEvent() of activity.
If I understand this correct I just want to know what is the purpose of going up of the MotionEvent in OnTouchEvents? We could handle every form of event from a simple click to custom gesture till the MotionEvent object reach the last listener of the last view in the activity. What's the use of OnTouchEvent() method and why it must go up to the activity?
I'm using two different layouts in my activity where in one activity i need to work with touch screen and in another activity it should not work on Touch screen.
How i can do it?
I tried to used dispatchTouchEvent to get the touch response but it gets for the entire activity, is there any way to get based on the layout ?
I used
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
.
.
.
return true;
}
if i used like this it disables all the touch event in my activity.
I know this got asked often, but all solutions(, I found,) don't work for me.
What I have is a CardView with an OnClickListener making a Toast (#toast1).
Inside the CardView there are multiple views as also a WebView.
As mentioned elsewhere, to pass through the click through the WebView to the CardView I have done following:
Set android:clickable="false" in WebView XML
insert following under CardView.setOnClickListener(...)
WebView.setOnTouchListener( (view, event) -> true);
I also replaced the lambda with an anonymous method, to see if its just this. No change.
What happens now is:
At the border and over the other views, the clickListener is triggered and the toast appears
Over the webView the clickListener isn't triggered.
Also put a toast (#toast2) in touchLstener of WebView before returning true, and it gets triggered.
What I expect:
Click will passed through WebView
With #toast2 added: First show #toast2 then #toast1
What is a bit confusing, that in documentation of OnTouchListener, the return is following:
True if the listener has consumed the event, false otherwise.
For me that means:
true: Don't pass click to below views, as listener consumed it
false: Pass click to below views, as listener didn't consumed it
But setting to false didn't change anything.
First of all I would suggest you to get familiar with android touch handling system - you can find a really good description in this answer. To sum it up: touch event propagation starts on top level of hierarchy, but actual handling of the touch event starts on the lowest level of view hierarchy. As for solution of your problem I may suggest to sublcass the parent of your WebView and override onInterceptTouchEvent in the following way:
#Override
public boolean onInterceptTouchEvent(MotionEvent e) {
return true;
}
This will instruct this parent view to intercept all touch events that would otherwise go to its children views, thus limiting the first level of touch processing to this view.
This doesn't seem like a typical view layout which I'm having trouble with.
I have two listViews.
Each listView has touchListener
(whose purpose is to synchronize scrolling by calling dispatchTouchEvent() to another listView)
ListView also has onItemClickListener to handle clicks on the row of listView.
Everything works as intended up to here.
I'd like to add another clickListener to subview-group of the listView's row to handle click event on the subview.
After attaching this clickListener, I see listView's scroll doesn't always work.
I suspect its because the clickListener of this child view is inspecting touch events (to see if its indeed a click) before the parent(listView)'s touchListener.
I can think of two workarounds to this problem.
attach touchListener instead of clickListener to child, and make it return false for all touch event except FINGER_UP event.
on FINGER_UP event, I execute the method which I initially had in onClickListener
public boolean onInterceptTouchEvent (MotionEvent ev)
Implement this method to intercept all touch screen motion events. This allows you to watch events as they are dispatched to your children, and take ownership of the current gesture at any point.
(ok... I'm confused, I thought touch events goes to child views first and propagate to parents if children don't handle the touches..)
.. How do I implement the method 1?
.. Please help me to figure out #2 as well and to grasp the touch delivery mechanism.
EDIT -
This is where I add OnClickListener to my subview.
viewHolder.layout_author.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent profileIntent = new Intent(ImageListAdapter.this.activity, ProfileActivity.class);
profileIntent.putExtra("JsonUser", jsonAlbumImage.jsonUser);
ImageListAdapter.this.activity.startActivity(profileIntent);
}
});
I'd like to add another clickListener to subview-group of the listView's row to handle click event on the subview.
You simply need to write a custom adapter and assign the OnClickListener in getView(). You can look at the question: Android GridView Button Click Handler for example code.
Also awhile back I answered Android. Scrolling 2 listviews together did you use a similar approach to synchronize your ListViews? When I combine both of the answers, my app functions the way you want. I hope this helps.
This question is a bit awkward. Is it possible to transfer the touch focus of one view to another? Basically, say that you have a view that picks up the first ACTION_DOWN touch event, and then immediately wants to transfer the focus for all touch events to another view to handle with it's onTouchEvent(MotionEvent event). I thought that doing the following would make it work, but it didn't:
#override
public boolean onTouchEvent(MotionEvent) {
this.clearFocus();
anotherView.setFocusableInTouchMode(true);
anotherView.requestFocus();
}
Obviously, it seems to me that it just doesn't work that way. Could someone explain to me how I can go about doing something like this?
If it's still a bit difficult to understand my question, think about a regular button. When pressed, the button is highlighted (focused) and if you move your finger off the button but still keep your finger on the screen, the button becomes unfocused but still has control of the entire touch events (no other view can become focused even if you move over them). My question asks if it is possible to transfer this touch focus to another view to handle without having you to remove your finger off the screen.
Try below code might work
button1.setOnFocusChangeListener(new OnFocusChangeListener()
{
#Override
public void onFocusChange(View arg0, boolean hasFocus)
{
if(hasFocus)
button2.requestFocus();
}
});
The way I worked around this was to have a single view "harness" whose sole purpose was to pass on the touch information to the other classes, who would then do the processing. Note that ViewA and B don't actually have to be views and extend the view class. Its not an ideal solution, but I don't think it's possible to solve this problem with the current Android framework (ICS/JB).
class ViewHarness extends View{
public boolean onTouch(MotionEvent event){
if(ViewA is selected)
ViewA.onTouch(event);
else
ViewB.onTouch(event);
}