Reputation: 5031
I have an ImageView
overlay inside of a RelativeLayout
and want to prevent any clicks from going through the ImageView
to the Buttons etc that are behind it (thus in effect disabling the entire RelativeLayout
).
Is the a simpler way of doing this then iterating the RelativeLayout views and setting them to disabled as I currently am doing using this code:
RelativeLayout rlTest = (RelativeLayout ) findViewById(R.id.rlTest);
for (int i = 0; i < rlTest.getChildCount(); i++) {
View view = rlTest.getChildAt(i);
view.setEnabled(true);
}
Upvotes: 30
Views: 32559
Reputation: 362
In C#, I use an empty delegate:
view.Click += delegate {};
I haven't encountered any problems with it but it does prevent clicks from filtering through to underlying controls.
Upvotes: -1
Reputation: 57
you can also se the root click listener to null:
// Do not process clicks on other areas of this fragment
binding.root.setOnClickListener(null)
This works 100%. It doesnt affect other listeners that are already set on the fragment's views.
Upvotes: 0
Reputation: 10761
You could use databindings and consume the clicks like this:
android:onClick="@{() -> true}"
Upvotes: 0
Reputation: 718
There is a much cleaner way
You can use:
android:onClick="preventClicks"
in XML and in your Activity
public void preventClicks(View view) {}
This works with fragments. Example inside this Activity has multiple fragments overlapping one another, just by adding the XML attribute in the background of your fragment it will still call the Activity.preventClicks and will prevent touches on fragments behind it
Upvotes: 17
Reputation:
Just add these two listeners:
// Set an OnTouchListener to always return true for onTouch events so that a touch
// sequence cannot pass through the item to the item below.
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
v.onTouchEvent(event);
return true;
}
});
// Set an OnHoverListener to always return true for onHover events so that focus cannot
// pass through the item to the item below.
view.setOnHoverListener(new OnHoverListener() {
@Override
public boolean onHover(View v, MotionEvent event) {
v.onHoverEvent(event);
return true;
}
});
Upvotes: 2
Reputation: 3734
The following solution works in the general case:
_container.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// NOTE: This prevents the touches from propagating through the view and incorrectly invoking the button behind it
return true;
}
});
It basically blocks any touches from propagating through the view by marking the touch event as handled. This works on both UI controls and layout containers (ie: LinearLayout, FrameLayout etc.).
The solution to set "clickable" as false did not work for me for layout containers either in code or in the view XML.
Upvotes: 10
Reputation: 157467
Simply call rlTest.setClickable(false)
. This will prevent the click to be propagate to the children
Upvotes: 23
Reputation: 1504
I assume that you are using onClickListeners.
How about using onTouchListener instead of onClickListeners. By doing this you will have a control over how deep down in your hierarchy the touch even can be visible. For example, if you have toch listeners on a relative-layout(RL) and a image-view(IV)(contained in RL), and you assign touchListeners to both. Now if you return true from IV's touch event, the lower down member RL will not receive the touch event. However if you return false from from IV's touch event, the lower down member RL will receive the touch event.
Hope this helps!
Upvotes: 2