How to Find Out What View a Touch Event Ended At

How to find out what view a touch event ended at?

It is very easy to detect your finally touched view, try this code

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint location = [[touches anyObject] locationInView:self.view];
CGRect fingerRect = CGRectMake(location.x-5, location.y-5, 10, 10);

for(UIView *view in self.view.subviews){
CGRect subviewFrame = view.frame;

if(CGRectIntersectsRect(fingerRect, subviewFrame)){
//we found the finally touched view
NSLog(@"Yeah !, i found it %@",view);
}

}

}

Detect when the touch event is over in Android

The MotionEvent object passed to the onTouchEvent(...) method has a getAction() method, you can use it to determine if the event is over. eg:

webViews.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//pointer down.
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
//event has finished, pointer is up or event was canceled or the pointer is outside of the view's bounds
break;
}
return false;
}
}

Also, if you want to consume the event (stop it from propagating) just make the onTouch(...) method return true instead of false.

How can you detect which view you are passing over when performing a touch event?

I found Sebastian Roth's answer very helpful with resources, but since it wasn't really an answer to my question, I thought I'd share what I came up with.

Here is the code I use to detect views ( only views that will accept a drop that is ) given a coordinate on the screen.

            private DropView findDropTarget( int x, int y, int[] dropCoordinates ){
final Rect r = mRectTemp;
final ArrayList<DropView> dropTargets = ((main) context).getBoardDropTargets();
final int count = dropTargets.size();
for (int i=count-1; i>=0; i--) {
final DropView target = dropTargets.get(i);
target.getHitRect(r);
target.getLocationOnScreen(dropCoordinates);
r.offset(dropCoordinates[0] - target.getLeft(), dropCoordinates[1] - target.getTop());
if (r.contains(x, y)) {
dropCoordinates[0] = x - dropCoordinates[0];
dropCoordinates[1] = y - dropCoordinates[1];
return target;
}
}
}

Ok, first off mRectTemp is just an allocated Rectangle so you don't have to keep creating new ones ( I.E. final Rect r = new Rect() )

The next line dropTargets is a list of views that will accept a drop in my app.
Next I loop through each view.

I then use getHitRect(r) to return the screen coordiantes of the view.

I then offset the coordiantes to account for the notification bar or any other view that could displace the coordiantes.

finally I see if x and y are inside the coordinates of the given rectangle r ( x and y are the event.rawX() and event.rawY() ).

It actually turned out to be simpler then expected and works very well.

Find a view (button) which a motion event ends on

Getting the SubView, If its within Linear Layout or GridLayout is possible by below method.

|*| I have shown u how to get SubView if Views are placed vertically inside LinearLayout.

NamVyuVar.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View view, MotionEvent MsnEvtPsgVar)
{
switch (MsnEvtPsgVar.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
Log.d("TAG", "onTouch: ACTION_DOWN");
break;

case MotionEvent.ACTION_MOVE:
LinearLayout NamLloVav = (LinearLayout)view;
float SubVyuHytVal = NamLloVav.getChildAt(0).getHeight();
float TchPntYcoVal = MsnEvtPsgVar.getY();
int NamIdxVal = (int) (TchPntYcoVal / SubVyuHytVal);

View NamIdxVyuVav = NamLloVav.getChildAt(NamIdxVal)

// CodTodo With the Indexed View NamIdxVyuVav :

break;

case MotionEvent.ACTION_UP:
Log.d("TAG", "onTouch: ACTION_UP");
break;
}
return true;
}
});

|*| Similarly If u want to get SubView if Views are placed horizontally inside LinearLayout Change below 3 lines.

float SubVyuWdtVal = NamLloVav.getChildAt(0).getWidth();
float TchPntXcoVal = MsnEvtPsgVar.getX();
int NamIdxVal = (int) (TchPntXcoVal / SubVyuWdtVal);

|*| Same technique can be applied for Grid Layout as well.

How do I detect if a touch event has landed within an EditText?

What exactly do you want to do? If you only want to detect if your EditText is touched, add an OnTouchListener to the EditText... or even OnClickListener.

Edit: If you want to detect outside, you can detect touch event in the containing view, and then, given you have your EditText view:

Rect editTextRect = new Rect();
myEditText.getHitRect(editTextRect);

if (!editTextRect.contains((int)event.getX(), (int)event.getY())) {
Log.d("test", "touch not inside myEditText");
}

Or you add a touch listener both to the EditText and the container, and return false in the one of the EditText, this way it will be intercepted and not forwarded to the parent. So, all the touches you detect in the listener of the parent, will not belong to the EditText.

How to detect view has been touched when dragged over from another view

I couldn't find a way to do this through the actual custom views and had to go one layer back.

The position of the views are documented on the FrameLayout that contains each view.

In the FrameLayout, I ended up overwriting onTouchEvent.

I ended up having to do something similar to this:

@Override
public boolean onTouchEvent(MotionEvent event) {

float xCoord = event.getX();
float yCoord = event.getY();

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Using X and Y coordinates, find out if touch event is on top of a view.
// Mark the view as touched
return true;
case MotionEvent.ACTION_UP:
// Action required once touch released.
return true;
default:
// When dragging, the default case will be called.
// Using X and Y coordinates, figure out if finger goes over a view.
// If you don't want same behaviour when going back to previous view,
// then mark it so you can ignore it if user goes back to previous view.

}
}

Once case MotionEvent.ACTION_UP gets called, you can use the fact that the views were marked to know which ones were touched. You can also get the order if required by putting the views in an array when marking them.



Related Topics



Leave a reply



Submit