Is it possible to pass an onTouchEvent to multiple views in Android?
Android will cascade down the views calling onTouchEvent
on each one until it receives a true
from one of them. If you want a touch event to be handled by all of them, then return false until it reaches the last one.
EDIT:
Ok. If I understand correctly, you have a single top view containing a bunch of child views one layer deep. My original answer was assuming that you had three custom views that were on top of each other in the ViewGroup's hierarchy (View3 is a child of View2. View2 is a child of View1. View1 is a child of ParentView). You want the user's touch event on the parent view to get sent to all of it's children.
If that's the case, AFAIK, there is no view in Android's API that allows that. So, you'll have to make a custom view that does it.
OK, I haven't tested this, so please tell me if it works and if it's what you're trying. Create a custom class that extends whatever object frame
is, then override the onTouch
method like so.
@Override
public boolean onTouchEvent(MotionEvent ev) {
for(int i = 0; i < this.getChildCount(); i++){
this.getChildAt(i).dispatchTouchEvent(ev);
}
return true;
}
Now, keep the same logic that your custom views have, except they should all return false
because your parent view will not receive the onTouch event unless they do as stated in my previous answer
note: with this implementation, the child view that the user actually touches will fire twice because the logic will go fire child touch event -> return false -> fire parent touch event -> fire child touch event again
StartingGroovy
Started with basic Java & Groovy. Aiming to learn more about programming in general as well as C++.
Updated on June 09, 2022Comments
-
StartingGroovy about 2 years
I have read a few questions regarding this topic on SO but haven't really found a solid answer to it.
I have a framelayout that I stack multiple custom views on, however the onTouch event only works with the top view. (the custom views are all the same view with the same onTouch event, just multiple of them)
FrameLayout
- customView[2] <--- this is the last view added and the only one that receives the event
- customView[1]
- customView[0]
I'm testing it on Android 2.2 and am wondering if there is any way for the other views below to know where the touch happened?
EDIT (Adding some code)
I'm adding some code to hopefully help explain where I'm running into issues. At first I just automatically had the
onTouchEvent
return true. This made it so that the last view (in my case customerView[2]) would be the only one generating a value.However, once I added the method to set the
onTouchEvent
to return true or false, now the only view returning a generated value is customView[0].I hope this clears up what I am asking. I'm rather new to this and I appreciate you taking the time to explain it (and of course I appreciate your patience).
Also, I realize that my TextView's don't update with the value on each touchEvent, I'm working on fixing that.
My Activity:
public class MyActivity extend Activity { CustomView[] customView; TextView[] textView; int numViews 3; //FrameLayout and Params created @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); for(int i = 0; i < numViews; i++) { customView[i] = new CustomView(this, i); //Allows the onTouch to be handled by all Views - View[0] is the bottom view if(i == 0) { customView[i].setTouchBool(true); //set view's onTouch to return true } else { customView[i].setTouchBool(false); //set view's onTouch to return false } //Set TextView to display the number generated by the CustomView textView[i].setText(Double.toString(customView[i].getGeneratedNumber())); //Add views to main layout frame.addView(textView[i]); frame.addView(customView[i]); } } }
My View:
public class CustomView extends View { boolean onTouchHandler = true; int xVal = 0, yVal = 0; int index; double generatedNum = 0; public CustomView(Context context) { this(context, 0); this.index = 0; } public CustomView(Context context, int index) { super(context); this.index = index; } @Override public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getAction(); switch(action) { case MotionEvent.ACTION_DOWN: { //do logic } case MotionEvent.ACTION_MOVE: { //do logic } case MotionEvent.ACTION_UP: { xVal = (int) ev.getX(); yVal = (int) ev.getY(); generateNumber(xVal, yVal, index); break; } } return onTouchHandler; } private void generateNumber(int x, int y, int index) { if(index == 0) { generatedNum = (x / 2) * (y / 2) + 64; } else { generatedNum = (x / 2) * (y / 2) + (index * 128); } } public double getGeneratedNumber() { return generatedNum; } public boolean setTouchBool(boolean b) { this.onTouchHandler = b; } }