I was trying to make an area so when ToggleButton is on, you are able to toggle buttons within this area and if ToggleButon is off, you won't be able to toggle the buttons within this area.
For this specific area I used a FrameLayout, so I can stack two LinearLayout on top of each other. So when I hit the Edit-Button, the one on top which is half transparent disappears with setVisibility(View.GONE) and you are now allowed to click the buttons now.
PROBLEM: The buttons in this area are always clickable
I was able to toggle them separately with button.setClickable(true/false) but is there a solution so you just can't click through the LinearLayout that is on top (like "not-through-clickable")?
Link to an image of the Layout: https://i.imgur.com/eTyhCDc.png
Desired behavior:
Hit EDIT -> half transparent Layout on top of blue Layout disappears -> TESTOFF1 and TESTOFF2 are now clickable.
-> Hit DONE -> the half transparent Layout appears on top again and the buttons below it are not clickable anymore (without using .setClickable for every single button).
The view on top gets first crack at any touch events. If the top view doesn't handle the touch then the view below get a chance on down to the bottom view. The top layer is a LinearLayout so, but default, it doesn't handle touches, so it allows the touch events to percolate down to the buttons which are happy to respond.
One way to resolve this is to place a touch listener on the semi-transparent view that just returns true. Thus, the LinearLayout will consume the events and not let the buttons see them.
When the view is gone, the buttons become the top view so they will see the clicks.
If you want to know more about how touch events are handled, read this Stack Overflow answer for an excellent explanation.
editButton.setOnClickListener {
button1.isEnabled = !button1.isEnabled
button2.isEnabled = !button2.isEnabled
editButton.setText(
if (button1.isEnabled) {
R.string.done
} else {
R.string.edit
}
)
transparentView.isInvisible = button1.isEnabled
}
This example is using kotlin and the Android KTX libraries
Java version
editButton.setOnClickListener(new OnClickListener {
button1.setEnabled(!button1.isEnabled());
button2.setEnabled(!button2.isEnabled());
editButton.setText(button1.isEnabled() ? R.string.done : R.string.edit);
transparentView.setVisibility(button1.isEnabled() ? View.INVISIBLE : View.VISIBLE);
});
Related
I have three layout layers and over the blue one, two views (EditText and a simply view), so let's put some context:
When I set on click listener only to yellow layer and touch inside the blue one for example, the click is listened only in the yellow layer, the click is transfer. ClickTransferBetweenChilds
When I set on Click listener in all layers the click listener is triggered when I touch anywhere inside each layer. ClickNotTransferWhenSetClickListener
This is the default android behavior and I call this layer stack, parent-child views, there's the following schema:
Yellow - is parent of -> Red - is parent of -> Blue.
Now focus on the blue layer, over the blue layer are super posed two elements, the EditText and the View, the EditText is over the View, and initially with the default android behavior when I touch the upper left side, the keyboard is called (because the EditText is below) but I want to avoid this behavior. Please call it brother propagation.
I make a simply solution please refer to line 71 Gist in MainActivity.java, but we can't implement in production because I can only touch the Layout things (the yellow one - Parent - at possible).
TL/DR: I want to avoid this behavior ClickTransferBetweenBrothers how to avoid transfer click between brothers keeping the click transfer between parent-child views.
I have this button that I have manually positioned at the bottom of the screen (I intentionally made it semi transparent so we can see the issue), over a BottomNavigationView.
I do this through this code:
val buttonFinalHeight = resources.getDimensionPixelSize(R.dimen.fullwidthbutton_height)
val screenHeight = context.displaySize().height
val rootPanelYLocation = root_filtersheet_panel.locationOnScreen().y
filter_gobutton.y = (screenHeight-rootPanelYLocation).toFloat()
That is, I manually set the Y coordinate of the view so I can position it at the bottom. The reason is that this Button belongs to a fragment that is positioned on top of the BottomNavigationView, but this button needs to be at the bottom of the screen, over any other views (including the bottom menu).
That means every layout containing this button has clipChildren=false so the button can overflow.
As you can see in the screenshot it works. However when I try to click on it the touch action is passed on to the bottomnavigationview instead to my button, as demonstrated by this ripple:
Now the button does accept click actions as demonstrated by this other screencap where I clicked in the topmost region that goes above the BottomNavigationMenu, again proven by the ripple effect on the button itself:
I have tried setting an onTouchListener on my button and playing with elevation numbers (BNV has 0 elevation, button has 16, but no change), but nothing seems to be working.
You could try removing the click listeners for the buttons below. And add them again when the fragment is closed.
I ended up modeling the button as a Dialog. Not the cleanest solution, but it gets the job done.
Here's my current situation: I can't click on the toolbar because there is a view that is overlapping it intercepting the touch responses. I'll expand: I'm making a music app. In the music app, there is a list of songs that is beneath the toolbar. However, once you click on a song, a panel opens up and slides up over the toolbar and continues into a transparent status bar. Pictures of this will be attached.
Now, obviously because this view is overlapping the toolbar I cannot actually use the toolbar for any touch events. But I need to. I cannot move the view below the toolbar because then my sliding up panel is limited to beneath the toolbar instead of overlapping it. If there is anyway to get around this, please let me know. I'd very much appreciate it.
So, in my current situation, I thought maybe I'd be able to touch the portion of the view that covers the toolbar and send that data to the view that contains the toolbar so I can detect touches on the toolbar. However, I cannot figure out how to do this, or even if it is possible.
My question is: How can I detect touches in the view beneath another view?
Here are the pictures:
Here is the list of songs:
And here is when the song panel is opened(I'm using an image of a tiger for any song that doesn't have art at the moment):
Thanks!
wtf?
You want that your user can touch on the toolbar which is not visible at the moment because its overlapped by another view? What kind of user would expect such a user experience?
I mean:
How does the user even know that he can click on a not visible element ^^
If the user magically knows somehow that he can click, how does he know where exactly he has to click. For example, he could also click on one of the toolbar menu items, but if he clicks a few pixel more left, then he would click on toolbar item 1 instead of toolbar item 2.
However, you have three possibilities:
You can make the overlapping view not clickable by overlappingView.setClickable(false);.
You could add a transparent view with an OnClickListener that has the same width and height as the toolbar over the overlapping view. In the OnClickListener you could simply invoke the desired method like onOptionsItemSelected() (fake the required parameters) or use an EventBus for communication.
Similar to the 2. option add a transparent view, but instead of setting a OnClickListener set a OnTouchListener by extending from View) and forward the MotionEvent to the Toolbar by calling toolbar.onTouchEvent(motionEvent);
If you really want to detect touch events of a view beneath another view you could set onTouchEvent of the foreground view to false. However, I advise you to rethink the layout in order to put the Toolbar on top so the users can see it otherwise they don't know what they are clicking on.
Here is the scenario; I have 3 PNG photos i wanna use as background of buttons or ImageViews and they are overlapping in a relative layout. kinda like this:
so the red button will be the biggest and go under all of them, then i will add green button on top of red and then yellow button on top of green. so that's how it looks like. each button has a PNG background as i said at the beginning.
Problem is I cant make the only visible area of each Button/ImageView clickable! Android kinda considers each at rectangle button/ImageView.
Any solution for this?
In your onTouchListener you should check whether the event (MotionEvent) is in the transparent area of the background or not.
Either you can make a separate onTouchListener for each view/button and return false if the event is in the transparent area (of the View argument) or you can make a single listener for all of the buttons, ignore the View argument and check all of your three views to determine in which one the event is.
I have designed an UI with some 5-6 buttons and 2 galleries. On click of a button a listView is shown partially (does not cover the entire screen) from top right corner. I want to disable the onClick and scrolling of other buttons and galleries when the listView is visible.
That is I want to achieve a scenario similar to that of alertDialog. I don't want to individually disable the onClick of each button as I may need to add or remove buttons later and maintaining the code may become a tedious work. Is there any way to to disable the onClick and scrolling in general.
PS : It would also be helpful if the onClick and scrolling of a layout can be disabled. In that case I can disable the onClick of all layouts other than that of the listView that pops up
use this-
button.setEnabled(false);
or
button.setVisibility(View.INVISIBLE);
You can use viewgroup like this
and can disable the click event of that view group.