I need to create a navigation drawer such that, the first menu contains 5 pre-defined items (these will never change). Below that first menu, I want to have a second menu that contains a variable amount of items with a custom layout.
Explained in an image:
Here is what my main activity looks like right now:
<android.support.v4.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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="48dp" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="#layout/nav_header_drawer" />
<ListView
android:id="#+id/drawer_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:choiceMode="singleChoice" />
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
Which works, except now I can't use the app:menu="#menu/navigation_drawer_items" property for NavigationView because the ListView items overlap the menu items.
Here is the menu XML:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Communicate">
<menu>
<item
android:id="#+id/nav_share"
android:icon="#drawable/ic_menu_share"
android:title="Share" />
<item
android:id="#+id/nav_send"
android:icon="#drawable/ic_menu_send"
android:title="Send" />
</menu>
</item>
</menu>
Is there a way that I can load the menu XML AND show a custom layout below the menu? Is there a different want to do this?
NavigationView does not seem to have support for custom footers. In my project I have made this little monster based on some other SO answers.
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
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"
android:background="#color/colorPrimary"
android:fitsSystemWindows="true"
tools:context=".ui.MainActivity">
...screen content...
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:elevation="0dp"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer">
</android.support.design.widget.NavigationView>
<View
android:layout_width="match_parent"
android:layout_height="21dp"
android:layout_alignParentBottom="true"
android:background="#drawable/bg_navbarscroll"/>
</RelativeLayout>
<include
android:id="#+id/premium_footer"
layout="#layout/drawer_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
What we have here are two nested NavigationViews. This may be a bit overkill but I wasn't able to make it work otherwise. This is based on the work in this question so all the credit goes there: How to add footer to NavigationView - Android support design library?
The real NavView is the inner one, it has the header, it has the menu, but it doesn't fit system windows. The first one fits system windows and handles the drawer movement. The problem you are facing is because the ListView does not know the size the content in NavView holds. So you need to make sure nothing is in the same layout so there is no overlapping. Your listView has to be in parent of the NavView parent. And because this will likely destroy the mechanism for controls of the DrawerLayout you need the first, outer NavigationView.
Alternatively if you can live without inflating menus in drawer just make a custom "old-fashioned" drawer like the ones before the NavigationViews appeared.
In my case I wanted to add some info text at the bottom of the drawer. After fiddling a bit I managed to obtain the desired result by adding a ConstraintLayout in the NavigationView:
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/bottom_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.navigation.NavigationView>
For now everything seems to be working, but there could be some hidden pitfalls.
A fixed (non-scrolling) footer in your navigation menu, can be achieved by wraping the NavigationView around another layout, like you've posted. you can arrange it, using LinearLayout for the footer items as shown below:
<android.support.design.widget.NavigationView
android:id="#+id/drawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="#+id/footer_item_1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center"
android:text="Footer Item 1" />
<TextView
android:id="#+id/footer_item_2"
android:layout_width="match_parent"
android:layout_height="48dp"
android:gravity="center"
android:text="Footer Item 2" />
</LinearLayout>
</android.support.design.widget.NavigationView>
You can use whatever you want in place of the TextViews. Structuring your bottom layout well is necessary to avoid overlapping of views.
Menu XML
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Communicate">
<menu>
<item
android:id="#+id/nav_share"
android:icon="#drawable/ic_menu_share"
android:title="Share" />
<item
android:id="#+id/nav_send"
android:icon="#drawable/ic_menu_send"
android:title="Send" />
</menu>
</item>
You can finally add onclick listeners to your layout
View navFooter1 = findViewById(R.id.footer_item_1);
navFooter1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do footer action
}
});
View navFooter2 = findViewById(R.id.footer_item_2);
navFooter2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do footer action
}
});
This will help you must set your custom adapter in recyclerView.
<androidx.drawerlayout.widget.DrawerLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".DrawerActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/purple_200" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/header_layout" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</com.google.android.material.navigation.NavigationView>
</androidx.drawerlayout.widget.DrawerLayout>
Related
I created a navigation drawer and listed menu icons. After that I had to include a custom layout bottom of the menu list.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:layout_gravity="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
ndroid:layout_height="?attr/actionBarSize"
app:titleTextColor="#color/white"
android:background="?attr/colorPrimary"
ndroid:theme="#style/ThemeOverlay.AppCompat.ActionBar" />
</FrameLayout>
<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_view_menu"
app:headerLayout="#layout/nav_header"/>
</android.support.v4.widget.DrawerLayout>
drawer_view_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_prof"
android:title="#string/my_profile" />
........other items here.......
</group>
<group android:checkableBehavior="single">
<item app:actionLayout="#layout/toggle_button"
android:title="#string/blank"
/>
</group>
toggle_button.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/left_rounded"
android:backgroundTint="#color/red"
android:text="#string/lang_en"
android:textColor="#color/white"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/right_rounded"
android:text="#string/lang_ar" />
Then it displayed the custom layout but it is aligned right side. I need this to be aligned center horizontally. Also attached a problem illustration below.
Problem illustration
After some research on the internet I came up with a solution.
Steps
Included my custom layout(toggle_button.xml) in NavigationView Layout.
NavigationView Layout
<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:layout_gravity="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
ndroid:layout_height="?attr/actionBarSize"
app:titleTextColor="#color/white"
android:background="?attr/colorPrimary"
ndroid:theme="#style/ThemeOverlay.AppCompat.ActionBar" />
</FrameLayout>
<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_view_menu"
app:headerLayout="#layout/nav_header">
<include layout="toggle_button.xml""/>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
2.Updated my custom layout for making toggle aligned center in bottom.
toggle_button.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_marginBottom="#dimen/margin_medium"
android:layout_gravity="bottom">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/left_rounded"
android:backgroundTint="#color/red"
android:text="#string/lang_en"
android:textColor="#color/white"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/right_rounded"
android:text="#string/lang_ar" />
</LinearLayout>
Also removed the second group from drawer_view_menu.xml
Done! It was as simple as that....
I have a menu drawer with several items, and for some reason the items don't take the whole width of the drawer, even though layout_width is match parent.
Here's the drawer_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/drawer_user_current"
android:title=""
app:actionLayout="#layout/nav_drawer_current_user_profile" />
</menu>
Here is nav_drawer_current_user_profile.xml
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="#+id/img_chat_room_icon"
android:layout_width="#dimen/size_large"
android:layout_height="#dimen/size_large"
android:src="#drawable/ic_person_avatar_blue_24dp" />
<TextView
android:id="#+id/txt_user_profile_nav_drawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="Current user"
android:textColor="#color/light_blue"
android:textSize="#dimen/nav_drawer_font_size" />
</LinearLayout>
The drawer itself is in this file base_layout.xml
<android.support.v4.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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_menu_chat"/>
And this is how the menu is rendered
How can I make the item to be in the right, and to take all the width of the drawer?
try
android:title="#null"
in menu item
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:layout_marginEnd="-65dp"
android:layout_marginRight="-65dp"
app:menu="#menu/drawer_menu_chat"/>
CURRENT STATE: NavigationDrawer with a NavigationHeader and NavigationMenu items. The items are large in number so scrolling is required in order to access the items towards the bottom.
REQUIREMENT: When scrolling down to the bottom, the NavigationHeader should stay fixed
Here's my activity_main layout file
<android.support.v4.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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="#00000000"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"
/>
</android.support.v4.widget.DrawerLayout>
Here's my navigation_header_main layout file
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical"
android:background="#3d3b3b"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<android.support.v7.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:src="#drawable/categories"
android:padding="1dp"
/>
</RelativeLayout>
P.S I am new to android dev. Please ask for more resources if required
Found a workaround. Definitely not the most efficient one. Please suggest if anything could be done from here.
<android.support.v4.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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView>
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="#00000000"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer">
<include layout="#layout/nav_header_main"
<android.support.design.widget.NavigationView>
Definitely works. But the header layout is redundant
I know its too old question but i sharing a solution that's working for me:
1. PLACE nav_header_main inside NavigationView
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/activity_main_drawer" >
<include layout="#layout/nav_header_main"/>
</android.support.design.widget.NavigationView>
2. ADD some empty item as suitable for your header height in #menu/activity_main_drawer file
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:enabled="false"
android:title=" " />
<item android:enabled="false"
android:title=" " />
<group android:checkableBehavior="single">
<item
android:id="#+id/home"
android:title="#string/home" />
......
</group>
</menu>
Hey guys I've come up with a solution for the nav_drawer and how we can implement the static nav_drawer without writing any extra coding.
I'm sharing git link of the project that I'm currently working on.
Thanks !!
Below is the activity_main.xml file and I've used Navigation View Menu
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_main_bg_shape"
android:orientation="vertical">
<Button
android:id="#+id/whats_cool"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="260dp"
android:layout_marginTop="400dp"
android:background="#drawable/buttonshape"
android:fontFamily="#font/delius_unicase"
android:shadowColor="#362802"
android:shadowDx="4"
android:shadowDy="3"
android:shadowRadius="10"
android:text="What's Cool"
android:textColor="#003931"
android:textSize="12sp" />
</LinearLayout>
<android.support.design.widget.NavigationView
app:headerLayout="#layout/nav_header"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#color/gray_white"
app:menu="#menu/nav_drawer"
android:layout_gravity="start"
app:itemTextColor="#color/darkBlue"
app:itemIconTint="#color/darkBlue"
>
<include layout="#layout/nav_header"/>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
And you don't need to make any changes into your header layout and nav_drawer.
Just wrap the navigation view into a linear layout
<android.support.v4.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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/nav_header_main"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#00000000"
android:fitsSystemWindows="true"
app:menu="#menu/activity_main_drawer"/>
</LinearLayout>
Remove orientation from RelativeLayout. It doesn't support it
Set android:gravity="bottom" for parent RelativeLayout of header view.
My mistake, It will still scroll. You need to have custom recycler view for your navigation menu. So it scrolls in it's own container
<com.google.android.material.navigation.NavigationView
android:id="#+id/NavigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/header_rectangle"
app:itemTextColor="#color/white"
app:headerLayout="#layout/hidder_layout"
app:itemIconTint="#color/purple_700"
android:layout_gravity="start"
app:menu="#menu/navigation_menu" >
<include
layout="#layout/hidder_layout"/>
</com.google.android.material.navigation.NavigationView>
Today I was thinking of a way to improve my tablet design, and I found this image
I wanted that so bad, as it looks amazing. I am searching google for about a hour now and I haven't come across any good tutorials. I've found this one: v21 Material Design for Pre Lollipop.
I started implementing this right away and everything I tried went completely wrong. The theming for the standalone actionbar needs to be the ThemeOverlay.AppCompat.ActionBar however on my phone layout I am extending the Theme.AppCompat.NoActionBar theme. (Theme is below)
It's just not clear what I should do to make something like the image above on Tablets and show the normal (custom) supportActionBar on Phones without messing up one of them.
Here is my AppTheme style (that I apply to my app)
<!-- Base application theme. -->
<style name="AppTheme" parent="#style/Theme.AppCompat.NoActionBar">
<!-- your app branding color for the app bar -->
<item name="colorPrimary">#color/primaryColor</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<!-- theme UI controls like checkboxes and text fields -->
<item name="colorAccent">#color/colorAccent</item>
</style>
Before you ask, yes I've found this quesion on SO, but no this isn't a duplicate question. The post that Chris Banes wrote didn't make things clear for me as well.
Is it possible to do this without destroying both the layouts? Thinking out loud, the reason for me to pick the custom toolbar was because I had included a custom searchview, but removed it. There is another view in the toolbar but I think that it could be removed if it's really necessary.
This is the layout of my phone version.
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:theme="#style/Theme.AppCompat.NoActionBar">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical">
<include android:id="#+id/toolbar" layout="#layout/toolbar"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appBarLayout"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/replaceFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/errorWarnings"
android:visibility="gone"
android:gravity="center"
android:layout_gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/errorIcon"
android:tint="#color/fab_material_red_500"
android:layout_centerVertical="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/errorDescription"
android:layout_below="#+id/errorIcon"/>
</RelativeLayout>
<com.tim.koers.wallpapers.UI.FilterButton
android:id="#+id/filterButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="16dp"
android:clickable="true"
android:src="#drawable/ic_menu_filter"
android:elevation="6dp"
android:tint="#color/fab_material_white"
android:visibility="gone"/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>
Here is my tablet layout:
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:background="#android:color/white"
android:layout_marginEnd="64dp"
android:layout_marginStart="64dp"
android:layout_marginTop="56dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- This is the secondary toolbar, 72dp also according to specs -->
<include android:id="#+id/toolbar" layout="#layout/toolbar"
app:layout_scrollFlags="scroll|enterAlways" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"/>
</RelativeLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:layout_marginEnd="64dp"
android:layout_marginStart="64dp"
tools:context=".MainActivity" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/replaceFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/errorWarnings"
android:visibility="gone"
android:gravity="center"
android:layout_gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/errorIcon"
android:tint="#color/fab_material_red_500"
android:layout_centerVertical="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/errorDescription"
android:layout_below="#+id/errorIcon"/>
</RelativeLayout>
<com.tim.koers.wallpapers.UI.FilterButton
android:id="#+id/filterButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:layout_margin="16dp"
android:clickable="true"
android:src="#drawable/ic_menu_filter"
android:elevation="6dp"
android:tint="#color/fab_material_white"
android:visibility="gone"/>
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
I found an article that implements this layout.
Create a Card Toolbar (Nested Toolbar) in Android
You can implement it to your tablet layout.
It is composed of a extended-height toolbar (blue) and a CardView with title and regular menu.
The basic structure:
<FrameLayout>
<!-- Extended Toolbar holding Drawer icon -->
<android.support.v7.widget.Toolbar />
<android.support.v7.widget.CardView>
<LinearLayout>
<!-- Card Toolbar -->
<android.support.v7.widget.Toolbar />
<!-- Divider -->
<View />
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
step1 double the height of the toolbar
step2 setting up the CardView as the secondary toolbar
step3 Java code
origin toolbar: set Navigation Icon
CardView toolbar: set menu and title
See More
Android 5.0 - How to implement this tablet layout from Material Design guidelines
Googling this Picture
After many hours of trying things out I've come up with the following code:
For your phone layout use this as a base:
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#style/Theme.AppCompat.NoActionBar">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"
style="#style/tabsWidgetIndicatorColors"
android:theme="#style/Theme.AppCompat.NoActionBar">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Put your content here -->
</FrameLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>
For your tablet layout use this as a base:
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:theme="#style/Theme.AppCompat"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:fitsSystemWindows="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="128dp"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"
android:id="#+id/actionToolbar"
/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/primaryColor"
android:minHeight="?attr/actionBarSize"
/>
</LinearLayout>
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="vertical"
android:layout_marginEnd="64dp"
android:layout_marginStart="64dp"
android:layout_marginTop="56dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- This is the secondary toolbar, 72dp also according to specs -->
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="#color/colorSecondary"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
android:minHeight="72dp"
style="#style/tabsWidgetIndicatorColors"
>
<!--android:background="?attr/colorPrimary"-->
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:background="#color/colorSecondary"
android:minHeight="?attr/actionBarSize"/>
<!--android:background="?attr/colorPrimary"-->
</RelativeLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- your content here-->
</FrameLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
In your main code use findViewById to find the Toolbar with the id #+id/toolbar and #+id/actionBar.
If you are on a tablet layout, both Toolbars should not be null. On a phone, the actionBar is null.
Check for that, and if it's not null, you will need to set the supportactionbar to the toolbar with the id #+id/actionBar, and you will need to inflate the menu on the toolbar with the id #+id/toolbar. While running the tablet/phone check, make a new private boolean accessible to your class named isInflateMenuEnabled. If the #+id/actionBar toolbar is not null, isInflateMenuEnabled should be false.
To wrap things up, this is the code:
public class MainActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener{
private boolean isInflateMenuEnabled = true;
private Toolbar mToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
//Check if it is a tablet or phone
mToolbar = (Toolbar) findViewById(R.id.toolbar);
Toolbar actionToolbar = (Toolbar)findViewById(R.id.actionToolbar);
if(actionToolbar != null){
isInflateMenuEnabled= false;
setSupportActionBar(actionToolbar);
actionToolbar.setTitle("");
mToolbar.inflateMenu(R.menu.menu_main);
mToolbar.setOnMenuItemClickListener(this);
}else{
mToolbar.inflateMenu(R.menu.menu_main); // Inflate the menu because there will be no menu inflated automatically anymore.
mToolbar.setOnMenuItemClickListener(this);
setSupportActionBar(mToolbar);
}
mToolbar.setTitle(getString(R.string.title));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return isInflateMenuEnabled;
}
#Override
public boolean onOptionsItemSelected(final MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
// This will be working with your menu clicks
}
}
I am tying to get transparent toolbar over RecyclerView contains custom Relative Layout i called it customHeader . my layout in the main activity is like:
i use android support design library v.22.2.1 and other support libraries with the same version
things are fine except that, i am getting toolbar with my primary color rather than transparent toolbar even though, i have removed background color from toolbar layout.
this is the result i have got:
What i want is transparent toolbar but should get filled with primary color only when i scroll up
my activity_main layout is:
<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">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/btnCreate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="#dimen/btn_fab_margins"
android:layout_marginRight="#dimen/btn_fab_margins"
android:src="#drawable/share"
app:borderWidth="0dp"
app:elevation="6dp"
app:pressedTranslationZ="12dp" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/vNavigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/WHITE"
app:itemIconTint="#color/primary_text"
app:itemTextColor="#color/primary_text"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer_menu"/>
</android.support.v4.widget.DrawerLayout>
then the layout in my fragment is:
<RelativeLayout 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">
<!-- Story list in main page -->
<com.creativeLabs.news.util.MySwipeRefreshLayout
android:id="#+id/swipe_refresh_story"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity$PlaceholderFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/list_view_story_list"
android:overScrollMode="never"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.creativeLabs.news.util.MySwipeRefreshLayout>
</RelativeLayout>
my customHeader layout is:
<?xml version="1.0" encoding="utf-8"?>
<com.creativeLabs.news.ui.view.SlideTopStory
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_marginBottom="#dimen/story_list_item_margin_vertical"
android:layout_width="match_parent"
android:layout_height="#dimen/slide_image_height">
<ImageView
android:id="#+id/ivStoryimage"
android:contentDescription="#string/story_title"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ProgressBar
android:id="#+id/loading_bar"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!-- A mask view -->
<View
android:background="#drawable/title_slide_background"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="70dip"/>
<View
android:background="#drawable/title_slide_background1"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="70dip"/>
<TextView
android:id="#+id/title"
android:layout_alignParentBottom="true"
android:textColor="#android:color/white"
android:textSize="#dimen/text_size_large"
android:gravity="center_vertical"
android:paddingLeft="#dimen/slide_image_title_padding"
android:paddingRight="#dimen/slide_image_title_padding"
android:paddingEnd="#dimen/slide_image_title_padding"
android:layout_marginBottom="#dimen/slide_image_title_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.creativeLabs.news.ui.view.SlideTopStory>
My app thems.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorControlNormal">#android:color/white</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
.......
.......
in the manifest -> application tag:
android:theme="#style/AppTheme.WithoutActionBar">
in my activities and fragments, i coded nothing regarding toolbar colors or any other treatments other than
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true);
toolbar.setNavigationIcon(getActionBarIconResource());
so, why toolbar is getting the app primary color? how can i get a transparent toolbar ..any help please?
Thanks in advance
<android.support.v7.widget.Toolbar
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
Check how u style is applied
Where u set it to transparent (alpha?)
View.getBackground().setAlpha(..) ;