Reputation: 469
I've seen a lot questions about having a translucent status bar on top of navigation bar like this:
But what I want to achieve is to have a non-translucent status bar and make navigation drawer header view same height as action bar. This works find for pre-lollipop devices (API < 21). But for API 21+, the entire navigation drawer just moved up and overlapped by status bar, instead of place below status bar. The only work around I can think of is to manually set layout_marginTop
on the header view for devices later than API 21+. Is there a better solution to fix this for all devices?
API < 21:
API > 21:
styles.xml(v21):
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>
DrawerLayout:
<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="false"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
I've tried to set fitsSystemWindows
to both true
or false
. No changes.
Here is my hack solution when initialize navigation drawer (and this is also answered by @AkashBhave):
LinearLayout navigationHeader = (LinearLayout) navigationView.getHeaderView(0);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
// This is make sure navigation header is below status bar
// This only required for devices API >= 21
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams) navigationHeader.getLayoutParams();
layoutParams.setMargins(0, getStatusBarHeight(), 0, 0);
navigationHeader.setLayoutParams(layoutParams);
}
Upvotes: 5
Views: 7323
Reputation: 141
Add -> In DrawerLayout
:
android:fitsSystemWindows="true"
and in NavigationView
:
android:fitsSystemWindows="false"
Upvotes: 10
Reputation: 1278
try this android:fitsSystemWindows="false"
<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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="false"
tools:openDrawer="start">
<include
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" />
Upvotes: 0
Reputation: 329
Make sure that fitsSystemWindows
is set to false
not only in your NavigationView
but also in your root DrawerLayout
element as well as in any of your content layouts.
I struggled with this problem for a while until I noticed an android:fitsSystemWindows="true"
which has been set in my old root layout element before I wrapped it up inside the DrawerLayout
.
I removed all occurences of android:fitsSystemWindows
and the status bar got respected for API 21+ as well.
<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"
>
<android.support.design.widget.CoordinatorLayout
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=".ui.ImprintActivity">
<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"
app:theme="@style/AppTheme.Toolbar"
app:titleTextAppearance="@style/Toolbar.TitleText"
app:contentInsetStartWithNavigation="0dp"
app:contentInsetStart="0dp"
>
<include layout="@layout/toolbar_logo_small"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_imprint"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="@layout/navigation_view_header"
app:menu="@menu/navigation_view_menu"
android:background="@color/primary_light"
/>
</android.support.v4.widget.DrawerLayout>
Upvotes: 11
Reputation: 7533
You can try setting the status bar color to transparent when the drawer is opened -
getWindow().setStatusBarColor(Color.TRANSPARENT);
Upvotes: 0
Reputation: 749
I think you should just set a margin_top
attribute to devices higher than API 21 +. You can retrieve the system API level with:
Build.VERSION_CODES.LOLLIPOP
This is how you could check for it and set it:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(left, top, right, bottom);
yourbutton.setLayoutParams(params);
}
Hope it helps!
Upvotes: 2