FragmentContainerView as the navigation view in DrawerLayout - android

I have a fragment that I sometimes want to display as a full screen and sometimes as the contents of the burger menu.
I have setup an activity with a burger menu like so:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ui.SomeActivity"
>
<!-- tools:openDrawer="left"-->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/my_menu_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="com.example.myapplication.ui.WhateverFragment"
android:background="#color/someBackgroundColor"
tools:layout="#layout/brand_feed_fragment"
android:clickable="true" />
<!-- clickable had no effect actually -->
.... activity UI here
</androidx.drawerlayout.widget.DrawerLayout>
The WhateverFragment has a RecyclerView and in each item I add a OnClickListener. When presented as a fragment of full screen activity that listener is invoked.
However, when i tap anywhere in my 'drawer' then it simply closes and my onclicklistener is not invoked in my fragment.
What am I missing?

As per #Mike-M:
The drawer should be listed last within the <DrawerLayout> tags in order for it to receive touch events properly. That is, move your <androidx.fragment.app.FragmentContainerView> to after everything in activity UI here.

Related

Android navigation drawer with tab layout in fragment

I am new to android and I am going to design this kind of layout that is complex to me. Here's the code of main_activity.xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/home_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout_home"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:menu="#menu/menu_drawer"/>
</android.support.v4.widget.DrawerLayout>
Basically I have in my main activity a Navigation drawer and 3 tabs. Here's a picture:
Everything works as I want and I'm happy.
When I click on a navigation drawer item I start a new intent to open a new activity and it's good but the drawer disappears of course (becase the new activity does NOT have the drawer). I want to keep the drawer in the screen always.
To keep the drawer on my screen I thought that I could have placed the TabLayout of the above XML as a fragment; in this way the drawer would still be there. But how can I do this? How can I place the TabLayout in a fragment so that I can replace this fragment with TabLayout or other fragments?
I think that I could put a FrameLayout instead of TabLayout but I do not know if it's good idea and how would it work. Any help?
There are similar questions like this but they haven't helped me because I'm still stuck here
More. If you click on results, the ThisSeason activity is launched and it has some fragments inside (inclusing ResultsFragments). That works, but there is no navigation drawe anymore and I have to press the back button!
I'll give you a general idea for implementing this.
Make a base activity for your application.
Then make fragment for each activity including the screen which has tabs. So, if you have 5 items in nav view then total of 6 fragments will be created.
Add the nav view and related functions in the main activity xml and java file. This will basically add navigation view to the base activity and since you're using fragments, all the pages(fragments) will have the navigation view.
Additional Note: You can make multiple subclasses to handle specific functions, like one for handling actionMode, navigation view and updating the title in the toolbar. You get the point.
Also, all the features which are common to all the fragments should be added in the base activity only instead of repeating the same code everywhere.

DrawerLayout with partially visible button

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

How can i use navigation side menu in entire app, even activity class?

I'm using android navigation drawer menu. I want to show navigation drawer in my all activities class. If i want to use it what i need to do actually. If anyone give tips it'll very helpful.
Make a BaseActivity Activity, which will be extended by every other Activity.
The layout of the BaseActivity will be a DrawerLayout, that contains a FrameLayout and the Navigation Drawer. It will look something like this (In this case, the Navigation Drawer is a RecyclerView) -
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Content-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/base_frame"/>
<!-- Side navigation drawer UI -->
<android.support.v7.widget.RecyclerView
android:id="#+id/nav_drawer_rv"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>
Make the FrameLayout a protected class field, and in every Activity that extends the BaseActivity, inflate the layout as such -
getLayoutInflater().inflate(R.layout.your_activity, baseFrameLayout);
Make the BaseActivity handle all interactions with the Navigation Drawer (selecting items, switching Activities, etc...).

Drawerlayout is intercepting all touch events

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.

Strange padding on the bottom after hide and show the fragment using the transparent status bar in DrawerLayout

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.

Categories

Resources