I am using Android Design Support Library to get navigation drawer pattern. I have following main activity layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/pl.dzielins42.skinflint.android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="http://schemas.android.com/apk/res-auto"
tools:ignore="MergeRootFrame" >
<!-- The main content view -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<android.support.design.widget.NavigationView
android:id="#+id/drawer_navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/view_nav_drawer_header"
app:menu="#menu/drawer" />
</android.support.v4.widget.DrawerLayout>
The container layout is where I inflate my fragments. Some of the fragments have Toolbar in their layouts. I use navigation drawer to move between these fragments. In each of the fragments with Toolbar I set it as activity's actionbar using setSupportActionBar, and later
supportActionBar.setDisplayHomeAsUpEnabled(true);
supportActionBar.setHomeButtonEnabled(true);
The problem is that on the first fragment (inflated in activity's onCreate) the "hamburger" icon is displayed properly, but after I change the fragment to another fragment with Toolbar, the icon changes to standard back-arrow.
I have tried to fix it by using ActionBarDrawerToggle (v7) and calling syncState in onDrawerClosed. This fixes it partially, as the "hamburger" icon is set but only after drawer is fully closed, so while it is still closing, back arrow-icon is visible.
Can someone provide better solution?
set the ActionBarDrawerToggle properly:
mDrawerToggle.setDrawerIndicatorEnabled(true);
Related
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.
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...).
I created a base activity and base layout to extend those to get same nav drawer and toolbar in all my activities. However, I want to add sliding tab layout in one of my activity. Should I create a new layout for this? Or is there a way I can add this sliding tab layout to my extended base activity dynamically?
activity_base.xml
<include android:id="#+id/app_bar" layout="#layout/app_bar"></include>
<android.support.v4.widget.DrawerLayout
android:layout_below="#+id/app_bar"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Listview to display slider menu -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#color/itembackground"
android:choiceMode="singleChoice"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector" />
</android.support.v4.widget.DrawerLayout>
You can implement the sliding tab in the Fragment which you are loading in the FrameLayout. The sliding tab can be achieved using a ViewPager and the ActionBar.TabListener interface. The ViewPager can hold the tab Fragments in a FragmentStateAdapter and access them using getChildFragmentManager(). This way, there is no need to create a separate layout for the tabbed screen, just extend from BaseActivity and use a Fragment with tabs.
For more on this, see the Creating Swipe Views with Tabs example.
I have an application with one activity that contains the navigation drawer. This activity also houses all the fragments that are associated with the navigation drawer.
What I'd like to do is have each fragment implement its own toolbar since some of these fragments might have a different theme or background for each toolbar in each fragment/screen.
The problem is once I have implemented a toolbar for each fragment, the hamburger icon disappears and is replaced with the back arrow. The navigation drawer still works, but the back arrow is misleading since the arrow should be a burger icon for each of those fragment connected with the navigation drawer.
What would be the correct way to implement a toolbar with the navigation drawer and have the freedom to change any property of the toolbar and keep the hamburger icon as well.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include layout="#layout/standard_toolbar" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/my_toolbar" >
</FrameLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical" >
<ListView
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#android:color/white"
android:choiceMode="singleChoice"
android:divider="#color/navigation_drawer_line_color"
android:dividerHeight="0.4dp"
android:listSelector="#drawable/list_selector" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
This is my code in the activity that houses the navigation drawer with child fragments as well as the toolbar.
getActivity().findViewById(R.id.toolbar) will give you reference to your Toolbar in your Fragments.
Hence, from this point you can control the background, inflate menus, change title, usually as you would with old ActionBar.
Regarding the theming of the toolbar programmatically, it is not possible.
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.