My drawerLayout is intercepting all touch events. I need help figuring out how to click on elements below it. Here is how my drawerLayout is set up
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frag_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
.... some code ...
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
I then reference this layout in another layout like this
<!-- elements inside of this relative layout
are unclickable because the drawer layout below
intercepts all clicks. If I place the drawer above
this view the drawer is beneath all the elements
in the relative layout, however, I am able to do
my clicks as expected. What I am doing incorrectly? -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ... some code * the buttons here are what
I want to be clickable when drawer is closed.
I currently cannot reach them ... -->
</RelativeLayout>
<include layout="#layout/drawer" />
</FrameLayout>
I have added android:clickable="false" and android:focusable="false" in the xml on the drawer. Programmatically I logged the clicks, and it is the actual drawer with id "drawer_layout" intercepting all clicks. Making it unclickable does not work, it is still clickable. I also tried setting the visibility to INVISIBLE and GONE and these are not viable solutions either.
How can I make that drawerLayout allow clicks through it to elements beneath it? Thanks in advance!
By setting clickable and focusable to false, I think you are disabling click to the views in the layout too. Remove these options from the drawer layout.
Try setting android:clickable="true" and android:focusable="true" for the container inside the drawer layout.
I figured this out. I ended up adding my main layout to the drawer which is the reverse of what I was doing before because before I was adding the drawer to my main layout. So the change I made was
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frag_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include layout="#layout/main_layout" />
</FrameLayout>
<RelativeLayout
.... some code ...
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
If anyone else runs into this problem it is view hierarchy conflict. You cannot have your drawer on top of elements that you want to interact it. If you have buttons or other widgets that you need to interact it you should include it to your drawer layout instead. I hope this helps someone else out there.
Related
Sorry I couldn't figure out a better title.
I have an XML with a DrawerLayout like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Frame layout for fragment -->
<FrameLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/Fragment_Container" />
<!-- Need a button visible here that moves left and right with the drawer -->
<!-- This is a right side drawer-->
<LinearLayout
android:orientation="vertical"
android:layout_gravity="right"
android:gravity="center_vertical"
android:layout_width="101dp"
android:layout_height="match_parent">
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
I'd like to have a button that's visible at all times on the screen, that when clicked opens/closes the DrawerLayout, so it should move in sync with the drawer.
I've tried putting it inside the drawer and offsetting it to the left, but it just stays a part of it's content.
The only other options I'm considering now is making it detect drawer movement and make it manually slide accordingly.
Bonus issue: It should be shown on top of the fragment i.e it should have higher z-index than the fragment loaded.
Thanks
whenever i open my navigation drawer frame layout contents are getting shown in background i even tried setting the frame's color white
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout"
tools:context="com.example.sumanravi.knowmycity.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/content_layout"
android:background="#color/white">
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
<ListView
android:layout_width="200dp"
android:layout_height="match_parent"
android:id="#+id/navList"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
If what you want to do is to hide the contents of a layout, you can:
Hide the whole layout (setting visibility to View.GONE or View.VISIBLE)
Change the alpha (setting alpha on the layout itself)
Remove all of the layout's children (please don't use this method, it's stupidly slow)
Containing views will always have their parent's background drawn underneath them. Another fun way to hide the content is to use the drawer listener: https://developer.android.com/reference/android/support/v4/widget/DrawerLayout.DrawerListener.html#onDrawerSlide(android.view.View, float) - look for onDrawerSlide(View, float) method and (for example) change the View's alpha as you go.
Another thing you could do with FrameLayouts is to set the foreground: set forground color in framelayout in android programatically
But generally, content under navigation drawers is always (at least partially) visible. If you're trying to hide it, you're probably not following the guide.
I used the way https://stackoverflow.com/a/27051852/3875363 to achieve the drawer behind the status bar, it seems fine before only stay for one view.
But I faced a strange case after I hide and show this fragment, a white padding appears on the bottom of the drawerlayout, it likes below.
I comment most codes to show a simple example.
The layout of activity:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
The layout of fragment with drawer
<android.support.v4.widget.DrawerLayout android:id="#+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/action_bar_in_list"
layout = "#layout/toolbar"/>
</RelativeLayout>
<com.ghostflying.portalwaitinglist.ScrimInsetsFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/debug_content"
android:background="#color/setting_item_group_title_text"
app:insetForeground="#4000"
android:fitsSystemWindows="true"
android:layout_gravity="start"
android:layout_height="match_parent"
android:layout_width="#dimen/navigation_drawer_width">
</com.ghostflying.portalwaitinglist.ScrimInsetsFrameLayout>
</android.support.v4.widget.DrawerLayout>
The layout of the second fragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment"/>
</FrameLayout>
Once I hide the drawer fragment, show the second fragment, then I popup the back stack to return. The drawer fragment will seem like the image, a padding with the height of status bar always appear. So strange.
Try to remove android:paddingBottom from DrawerLayout.
android:paddingTop makes Drawer doesn't cover the Status Bar, but there is no reason to duplicate padding at the bottom.
EDIT:
After your update, I analyzed it once more and I think your issue can be caused by your unusual design. All guides suggest that DrawerLayout should be root element of view hierarchy (as in your example you provided). See here: link
So I suggest one of these solutions.
Use separate Activities to display Views with and without Drawer. (I recommend this, especially when your Drawer plays navigational role.)
Use one Activity with Drawer Layout as root and put Fragments as Drawer's main content. If you don't want Drawer to be openable use this method after changing Fragment:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
Try to remove the android attribute:
fitsSystemWindows = "true"
This worked for me.
According to the official documentation it's a
Boolean internal attribute to adjust view layout based on system
windows such as the status bar. If true, adjusts the padding of this
view to leave space for the system windows.
I have a problem with my layout. I use ViewPager tab layout in my app and I would like to use transparent action bar. I managed to prevent the elements from hiding behind action bar, but the problem is that elements sill hide behind the tabs bar. How to fix it?
xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="?android:attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#E3F6CE">
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Use CoordinatorLayout to wrap all components and use this app:layout_behavior="#string/appbar_scrolling_view_behavior" in your RelativeLayout where xmlns:app="http://schemas.android.com/apk/res-auto"
I notice that the drawers within the Google applications are scrollable, but I cannot for some reason come to the conclusion of how to achieve a scrollable DrawerLayout. I attempted to construct the layout file with the following design paradigm.
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mainScreen">
<!-- Layout of Activity -->
</FrameLayout>
<!-- DrawerLayout segment -->
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/drawerLinearLayout"
android:orientation="vertical"
android:layout_width="260dp"
android:layout_height="match_parent"
android:layout_gravity="start|bottom"
android:layout_marginTop="?android:attr/actionBarSize"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#77000000">
<!-- Layout of Drawer -->
</LinearLayout>
</ScrollView>
</android.support.v4.widget.DrawerLayout>
But, with or without the ScrollView, the drawer just cuts items off at the bottom when they go beyond the end of the screen. I can't get any form of scrolling enabled. Not sure what I am missing or need to enable. Thoughts would be appreciated.
The LinearLayout in the DrawerLayout segment contains different styled views. One view displays title only with a divider below it, one displays an imageview with text next to it and another displays a title with a switch built into the row. So, multiple styled views need to be accounted for if done outside of XML coded layout files.
While using a ListView is a valid option, it was useful for me to attempt and resolve the situation for which I already had such a large XML file constructed for my layout in between the ScrollView above. As it turned out, there were only a few small modifications needed in order to get it working as intended. The latest layout file constructed is the following:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mainScreen">
<!-- Layout of Activity -->
</FrameLayout>
<!-- DrawerLayout segment -->
<ScrollView
android:id="#+id/scrollView"
android:layout_width="260dp"
android:layout_height="match_parent"
android:layout_gravity="start|bottom"
android:layout_marginTop="?android:attr/actionBarSize">
<LinearLayout
android:id="#+id/drawerLinearLayout"
android:orientation="vertical"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#77000000">
<!-- Layout of Drawer -->
</LinearLayout>
</ScrollView>
</android.support.v4.widget.DrawerLayout>
The main modifications required me to alter where the gravity and the margin existed. The gravity needed to be in the surrounding ScrollView otherwise it would cause odd behavior that didn't scroll or actually crashed in some instances apparently. Then the inner layout needed to be changed to 'wrap content'.
If the margin was not moved into the ScrollView as well, it apparently doesn't scroll down to the bottom. It left a margin of scroll unscrolled at the bottom. Once this was resolved, the DrawerLayout worked as was expected at this point. The ListView option also proposed is another approach to be used, but as mentioned at this point it was worth me analyzing it a bit further to re-use the code that I already had written; especially with several different custom views that would need to be handled inside the view.
It seems that it only works properly with a ListView. You will take less time to migrate to ListView than trying to make the ScrollView to work.
You should use a listview along with the frame layout. Something like this :
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
<ListView android:id="#+id/left_drawer"
android:layout_width="180dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
You can also refer to the Navigation Drawer documentation at developer.android.com. It has everything you will need.