41732

How to detect when any child view recieves a click

Question:

Given an arbitrary ViewGroup G with an arbitrary collection of child views, how can I detect when the user clicks on any of the child views? In this case, I want to draw a highlight for G.

I could add an onClick listener for each child, but I'm trying to avoid that so that the code doesn't have to be changed when the layouts change.

Alternatively, I could add onTouch handlers to G and set the highlight during ACTION_DOWN. However, this would trigger for actions that don't actually result in clicks, such as a swipe (the swipe could be handled by ViewPager, for example, and ultimately be irrelevant to G).

My layout for G has the focusable attributes:

android:focusable="true" android:focusableInTouchMode="true"

Thanks.

Answer1:

Here is how I do it:

//in onTouch method of parent, I get the coordinates of click int x = ((int) motionEvent.getX()); int y = ((int) motionEvent.getY()); //obtain the clickable arrea of the child as HitRect Rect clickRect = new Rect(); Rect rect = new Rect(); imageView.getHitRect(rect); //ask if the area contains the coordinates of the click if(rect.contains(x, y)){ //do some work like if onClickListener on the child was called. return false; //you clicked here, don't need to handle other Childs } //ask for other childs like before...

Now, you can target the parent as the delegate of all clicks done inside it, even if it is done in a child.

<hr />

<strong>EDIT:</strong>

To ignore other touch event that are not click, you can ask for how much user moved the finger:

case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_CANCEL: if (Math.abs(motionEvent.getRawX() - initialTouchX) > 5 || Math.abs(motionEvent.getRawY() - initialTouchY) > 5) { return true; // user mover finger too much, ignore touch } return false; // finger still there waiting for click

I give a square of 10 pixels to permit a confortable click, and if you exit it, I ignore it.

<hr />

<strong>EXTRA:</strong>

Here is the <a href="https://stackoverflow.com/a/50375336/2835520" rel="nofollow">complete code</a> for click and long click with onTouchListener.

Answer2:

You could use the View.getChildCount() to loop through all child views and see if the touch intersects with the child view. This involves getting x and y positions and calculating if it fits within the child view, use View.getChildAt(position) to get the reference to the child view .

So it would be something like this:

int childNr = theView.getChildCount(); for (int i = 0; i < childNr; i++){ YourView tmp = (YourView) theView.getChildAt(i); if(tmp.intersects(x, y)){ do some work } }

here you would have to put your view variable instead of theView and the class name which handles the views instead of (YourView) and x, y are the coordinates of the pressed spot.

Answer3:

In your XML, you could add point all the children to the same onClick method. Inside that method you could draw the highlight to G and then do something (or nothing) for the individual child view.

Recommend

  • SendMessage WM_LBUTTONDOWN/UP works on buttons but not window
  • libgdx distorted texture when using camera.setToOrtho(false, GAME_WIDTH, GAME_HEIGHT);
  • Strange jumping values for onTouchListener using a RelativeLayout in Android
  • Move Object along a straight line
  • Showing color selected from an image on touch event in an overlay
  • why getEdgeFlags() always return 0
  • Visual Studio macro/anything else to iterate through all projects and set project properties
  • Getting All x and y coordinates from a motion event in android
  • Image Map-like Blackberry Control - CLDC Application
  • Can I create EventListener in AS3 from one Object and remove it from another Object?
  • How to notify parent's view model when child's view model property is changed?
  • Writing to class member through const &
  • How to automatically pop-up keyboard?
  • Getting coordinates of a component in java
  • LibGdx GLES2.0 cube texel stretching
  • Toolbar shifts up, when soft keyboard appears
  • Receive list of elements in their visual order
  • How to display a tooltip according to mouse position? - JavaFX
  • How to get listview position?
  • Syntax error on tokens, AnnotationName expected instead - error on query
  • WPF version of .ScaleControl?
  • Android Activity.onWindowFocusChanged doesn't get called from within TabHost
  • Zoom in and out of jPanel
  • Force show.bind execution
  • gspread or such: help me get cell coordinates (not value)
  • Disable Enter in editText android
  • Opengl-es onTouchEvents problem or a draw problem? [closed]
  • Trying to switch camera back to front but getting exception
  • align graphs with different xlab
  • Free memory of cv::Mat loaded using FileStorage API
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • Angular 2 constructor injection vs direct access
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Linking SubReports Without LinkChild/LinkMaster
  • Easiest way to encapsulate a HTML5 webpage into an android app?
  • Programmatically clearing map cache
  • Running Map reduces the dimensions of the matrices
  • Sorting a 2D array using the second column C++
  • java string with new operator and a literal
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize