Android, How to make a transparent status bar correctly - android

I'm trying to make transparent status bar on Android 4.4+
I know how to make it transparent by defining my own style:
<style name="Theme.MyTheme" parent="Theme.MyTheme.Base">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item> </style>
I found here:
https://stackoverflow.com/a/20573595/2633630
The problem is that when status bar is transparent, it doesn't match the color of the action bar and the activity in the background is seen:
So I found that I can use android:fitsSystemWindows="true" and android:clipToPadding="false" in my layout that I found here http://mindofaandroiddev.wordpress.com/2013/12/28/making-the-status-bar-and-navigation-bar-transparent-with-a-listview-on-android-4-4-kitkat/
<LinearLayout 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:background="#color/background_darkRed"
android:fitsSystemWindows="true"
android:clipToPadding="false"
tools:context="com.sandak.......">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
....
That solves the top problem with transparent status bar and looks ok.. Unfortunately there is problem at the bottom on the "nav bar" with the system buttons, which is red and not transparent as I wish:
I was trying all possible variants to achieve working result, but I cannot figure out how to solve it. My only working solution is set top padding about 60dp to the root element. But this solution is ugly and on different devices can look different and may be not working.
I found a few applications on Google Play which working Ok with transparent background, so I'm curious how they make it work.
For example:
https://play.google.com/store/apps/details?id=com.trello and few others

//UPDATE:
Ok, this is quite old answer. Now you can use Material theme to handle this and it is pretty easy. Just set target api to 21+, use support library if you need to and create theme with material theme where you can specify status bar color directly
<style name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar">
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">#color/color_primary</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#color/color_primary_dark</item>
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#color/accent_orange</item>
</style>
=======================================================================
OLD ANSWER:
Ok, It seems that I solve my problem. It is not the best and clearest solution, but it is working solution.
If anybody in the future will find out better and more clear solution, please let me know and I will update my answer / or mark your answer as correct one. But for now, I have no better solution than this little hack:
The root element of the layout has to be RelativeLayout. Than should follow your main layout like ScrollView or any kind of others layouts, it doesn't matter. At the end before closing Relative Layout tag follows empty LinearLayout which has set the same background as your Action Bar and fixed height (height of Status Bar).
<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"
tools:context="com.sandak....">
<ScrollView
android:fitsSystemWindows="true"
android:clipToPadding="false"
android:layout_width="match_parent"
android:layout_height="match_parent">
.... all your main views etc..
</ScrollView>
<LinearLayout
android:id="#+id/statusBarBackgroundLinearLayout"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="30dp"
android:background="#color/background_darkRed"
android:clickable="false"
android:focusable="false">
</LinearLayout>
</RelativeLayout>
Ok then you have to set in code the same Linear Layout height as the Status bar has:
private void setStatusBarBackground(View rootView) {
setStatusBarLayout(rootView);
statusBarHeight = getStatusBarHeight();
setStatusBarLayoutHeight(statusBarHeight);
}
private void setStatusBarLayout(View rootView){
statusBarBackgroundLinearLayout = (LinearLayout) rootView.findViewById(R.id.statusBarBackgroundLinearLayout);
if (isPreKitkatDevice()) {
hideStatusBarLayout();
}
}
private int getStatusBarHeight() {
int statusBarHeight = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
private boolean isPreKitkatDevice(){
return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT;
}
private void hideStatusBarLayout(){
statusBarBackgroundLinearLayout.setVisibility(View.INVISIBLE);
}
private void setStatusBarLayoutHeight(int height){
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) statusBarBackgroundLinearLayout.getLayoutParams();
layoutParams.height = height;
}
And then just call setStatusBarBackground in your onCreate() method. This is working solution for all different kind of deviceas. For pre KitKat devices where transparent background is not allowed you have to hide the Linear Layout.

Related

Showing content behind status and navigation bar

This looks like a duplicate question but I am not able to do it. I want complete transparent(not translucent) status bar as well as navigation bar and want the content to appear behind them.
activity_details.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
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"
tools:context="com.bitspilanidvm.bosm2017.DetailsActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/q"
android:scaleType="centerCrop"/>
</LinearLayout>
v21 styles.xml
<resources>
<!-- Theme for API level > 21 -->
<style name="AppTheme" parent="AppBaseTheme">
<!--Customize your theme here. -->
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
</style>
In the activity java file
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
This is what I get.
How to get content behind the navigation bar?
If I add
<item name="android:windowTranslucentNavigation">true</item>
to my styles.xml
Here is what I get
As you can see, the content goes behind navigation bar but the navigation bar has to be translucent for this.
Is there any solution for this?
Add the FLAG_LAYOUT_NO_LIMITS flag within the Window. This will work for Android KitKat and above APIs. Example of this would be something like this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
The reason why the FLAG_FULLSCREEN doesn't work is simply because the FULLSCREEN flag is for removing screen decors like status bar(which works for you). However Navigation bar is not a screen decor. The LAYOUT_NO_LIMIT flag allows the window to extend beyond the screen limit, hence Navigation bar also gets covered within this flag.
Also you could simply hide the navigation and status bar by setting the app in immersive mode.
EDIT
The API ViewCompat.setOnApplyWindowInsetListener solves issues which the android:fitsSystemWindows=”true” does not and window insets can be applied to a particular view. An example of this.
ViewCompat.setOnApplyWindowInsetsListener(toolbar, (v, insets) -> {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
params.topMargin = insets.getSystemWindowInsetTop();
return insets.consumeSystemWindowInsets();
});
Standard layouts like FrameLayout , LinearLayout or RelativeLayout will not pass window insets to their children, whereas material layouts will do (e.g. DrawerLayout , CoordinatorLayout ). So we can change our layout to any material one, or we can subclass a standard layout and pass the insets to the children of layout ourselves. We just have to override onApplyWindowInsets method.
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; ++index)
getChildAt(index).dispatchApplyWindowInsets(insets);
// let children know about WindowInsets
return insets;
}
Reference Documentation:OnApplyWindowInsetsListener, WindowInsets
I wanted to comment the accepted answer but i can't yet.
Just to warn everyone who'll take this approach
The FLAG_LAYOUT_NO_LIMITS let extend your root view outside of the screen bounds creating other concerns about your layout design. For example, this flag simply breaks form readability by forcing the system to ignore "adjustPan" and "adjustResize" flags
So, even though i still consider Ahbi's answer as the correct one, make sure that nothing breaks outside of the scope of this flag
BETTER SOLUTION:
Actually, i've just found a better way to achieve the same result, without breaking anything
This is my style file
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:navigationBarColor">#android:color/transparent</item>
</style>
And these are the flags that i set programmatically
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
Setting the flag LAYOUT_HIDE_NAVIGATION (in combination with the style items) did the trick and my form still reacts to the adjustPan flag
If you want the image showing behind the status bar
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
but by doing this, fitsSystemWindows="true" is not working
toolbar overlaps to status bar.

Can I have "adjustResize" soft keyboard behavior and a toolbar behind the status bar at the same time?

In my Android app, it is vital for me to use the adjustResize behavior for the soft keyboard. So users can scroll down to other UI elements, such as a "continue" button.
I've noticed that that adjustResize only works when I have both the Manifest setting and android:fitsSystemWindows="true" in the layout root element. (Please correct me if I'm wrong!)
But with android:fitsSystemWindows="true" the Toolbar no longer sits behind the Status Bar. Which makes perfect sense, but isn't what I want.
When the Toolbar sits behind it, the status bar has a matching darker shade of my Toolbar's color. What I have with android:fitsSystemWindows="true" is a colorless status bar and a toolbar that sits 24dp lower than I want it.
I will give up the matching colored Status Bar for the sake of the adjustResize keyboard behavior. But my question is, is it possible to have both? Dare I dream for both Beauty and Accessibility?
Anyone more experienced know the magical combination of settings?
Or perhaps, as a work around, a way to explicitly color the status bar?
fyi:
These are Activities with RelativeLayout root elements, and there are ListViews and EditTexts in some of them.
Toolbar is android.support.v7.widget.Toolbar
Potentially relevant Style items:
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">#null</item>
PS - I've read dozens of similar-ish questions on soft keyboard behavior, but was unable to find anything helpful on unintended effects to the Toolbar. Also vice versa, lots of Style questions about toolbar/statusbar behavior, but nothing seemingly relevant. Never the less, sorry if I missed something!
Many thanks in advance!
Edit
I've been playing with removing android:fitsSystemWindows="true" and adding more ScrollViews or trying to get everything into the same ScrollView. This does nothing.
If I remove android:fitsSystemWindows="true" then the bottom of the UI is "glued" to the bottom of the screen -- it does not "resize" to instead glue to the top of the soft keyboard like I would expect it to do with adjustResize set in the Manifest.
Setting android:fitsSystemWindows="true" in the root view makes the UI resize like I would expect -- but it also makes the toolbar no longer draw behind the statusBar.
So I am still exactly where I started :(
Adding a layout XML code sample:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- CoordinatorLayout because this view uses SnackBars -->
<!-- Relative Layout to lock "continue" button bar to bottom -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Main content, that scrolls with or without keyboard -->
<!-- Correctly sits behind transparent Status Bar -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/footer_persistent_height">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ACTUAL VIEWS DELETED FOR BREVITY / CLARITY -->
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
<!-- Bottom nav bar -->
<!-- Correctly sits at bottom of UI when keyboard is not visible -->
<!-- PROBLEM: Not accessible when soft keyboard is visible -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
style="?android:attr/buttonBarStyle">
<Button
android:id="#+id/skip_button"
android:theme="#style/ButtonContinueGrey"
android:onClick="skipClickHandler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
<Button
android:id="#+id/button_progress"
android:theme="#style/ButtonContinueColored"
android:onClick="continueClickHandler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
</LinearLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
I have found a solution that seems to work well with the OS. First set fitSystemWindows = true to the view you want to be reacting to the window and then tell it to ignore the top padding:
ViewCompat.setOnApplyWindowInsetsListener(yourView, (view, insets) ->
ViewCompat.onApplyWindowInsets(yourView,
insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0,
insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()))
);
Read more here: https://medium.com/google-developers/why-would-i-want-to-fitssystemwindows-4e26d9ce1eec
I think you can try to use "adjustPan" instead of "adjustResize" when android:fitsSystemWindows="false". It works for me.
Try to keep your layout in scroll view and remove android:fitsSystemWindows="true" and use only adjust resize
I didn't got your question properly but as far I can understand to solve the problem-
For the padding problem try adding
android:fitsSystemWindows="true"
android:clipToPadding=”false”
And for the transparent status bar add
<item name="android:statusBarColor">#android:color/transparent</item>
to your AppTheme.
Hope it helps rest please upload the screenshot of your problem for detailed problem view.
(Answering my own question)
This does seem to be a bug in android:
https://code.google.com/p/android/issues/detail?id=63777
Posts on the above bug report link to a few suggested work arounds, like creating a custom Layout class or custom Soft Keyboard.
I feel like I've already wasted enough time with this. So my solution is to just manually color the Status Bar.
Solution:
Set android:fitsSystemWindows="true" in either the Layout's root view or globally in style.xml. This (along with adjustResize in the manifest) makes the UI shrink above the Soft Keyboard so no UI is blocked -- the most important thing.
Color the Status Bar. This is only possible in Lollypop and newer. Which is the same as the transparent StatusBar, anyway.
private void updateStatusBarColor(){
// Check Version
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// OPTIONAL: Calculate a darker version of the toolbar color
int color = calculateDarkerColor(toolBarColor);
// Get the statusBar
Window window = getWindow();
// You can't color a transparent statusbar
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
// Set the color
window.setStatusBarColor(color);
}
}
// Calculate a darker version of a given color
// Note I do this because the color always changes, if it's always the same I would save the darker version as a Resource in colors.xml
private int calculateDarkerColor(int color){
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] *= 0.8f; // smaller = darker
return Color.HSVToColor(hsv);
}
Its working for me.
In manifest.xml, put this in <activity> tag.
android:windowSoftInputMode="adjustResize"
In your layout's parent tag, put this.
android:fitsSystemWindows="true"
android:clipToPadding="false"
In styles.xml, put this.
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
I have done this with minSdkVersion 16 and targetSdkVersion 26
Here's what worked for me in order to have both a transparent status bar AND working adjustResize keyboard behavior.
First of all, I suggest you watch this 27-minute droidcon talk by Chris Banes, it can be enlightening: https://www.youtube.com/watch?v=_mGDMVRO3iE
In the layout add fitsSystemWindows on the correct level, so that the background image spreads under the status bar. Now fitsSystemWindows will fix the keyboard-layout behavior related to adjustResize.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- EditText etc here -->
In the Activity:
makeStatusBarTransparent(this);
setContentView(R.layout.activity_login);
The extension method:
fun Activity.makeStatusBarTransparent() {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
decorView.systemUiVisibility += View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// or:
// decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
statusBarColor = Color.TRANSPARENT
}
}
In the activity tag in the manifest:
android:windowSoftInputMode="adjustResize|stateHidden"
I've decided to do ".systemUiVisibility += ..." so I can set some things like windowLightStatusBar on the theme through xml (I override it in different flavors). But you can specify the LIGHT_STATUS_BAR flag directly (or not, depending on your background).
Keep in mind that fitsSystemWindows overrides padding, so you need to use another layout if you use padding.
I have fix your issue, and also tested at my end. Please change your relative layout to framelayout like this:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- CoordinatorLayout because this view uses SnackBars -->
<!-- Relative Layout to lock "continue" button bar to bottom -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- Main content, that scrolls with or without keyboard -->
<!-- Correctly sits behind transparent Status Bar -->
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="24dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ACTUAL VIEWS DELETED FOR BREVITY / CLARITY -->
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>
<!-- Bottom nav bar -->
<!-- Correctly sits at bottom of UI when keyboard is not visible -->
<!-- PROBLEM: Not accessible when soft keyboard is visible -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
style="?android:attr/buttonBarStyle"
android:layout_gravity="bottom">
<Button
android:id="#+id/skip_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
<Button
android:id="#+id/button_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
style="?android:attr/buttonBarButtonStyle"/>
</LinearLayout>
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>

Android: Transparent status bar with dynamic actionBar colors and DrawerLayout

I have an activity with a DrawerLayout. Our client requires us to dynamically change the action bar color and the corresponding status bar color of this activity depending upon the item selected from the DrawerLayout. This is easily done. However, my problem is that I am not being able to keep the status bar transparent when I dynamically change the status bar color. When I open the drawer, the colored status bar covers the top of the DrawerLayout like this:
However, I would like my DrawerLayout to look like this:
This I can do with the following line:
<item name="android:windowTranslucentStatus">true</item>
However, my problem is not that I can't set the transparency of the status bar. My problem is that the dynamic changing of the status bar and action bar color doesn't work with windowTranslucentStatus. My status bar color remains the colorPrimaryDark (the mustard-yellowish color visible on the status bar in the pictures above) even after I call getWindow().setStatusBarColor().
Now, I followed this tutorial and this and this stackoverflow questions among many others, but was unable to resolve the issue. All of these articles say that the ActionBar will move to the top, underneath the status bar (so that the status bar overlaps the action bar) once I set the windowTranslucentStatus to true. Afterwards, I should be able to add some padding to the action bar and simply changing the action bar color would also result in a darker status bar of the same color since the status bar is actually translucent and overlapping my action bar. However, for some reason, this does not happen in my case. The action bar stays where it is whether I set fitsSystemWindows to true or false or remove the attribute altogether. The action bar is always below the status bar which is, of course, always yellow if I set transparency.
I have also tried setting an alpha to the status bar color when changing it programmatically. This does make the status bar somewhat transparent, but it looks odd since it is not really dark anymore. Removing the CoordinatorLayout is of no help, either. I have spent several hours trying to fix this and am quite frustrated now. Any help is greatly appreciated.
My activity_main:
<?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_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">
<include layout="#layout/nav_header_main" />
<android.support.v7.widget.RecyclerView
android:id="#+id/nav_menu_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/nav_header_height"
android:clipToPadding="false"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/size_14dp"
app:layoutManager="LinearLayoutManager" />
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
And here is the XML for my app_bar_main:
<?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: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:theme="#style/AppTheme.AppBarOverlay"
app:elevation="0dp">
<FrameLayout
android:id="#+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
<com.quintype.sakshipost.Widgets.CustomMaterialSearchView
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
Your problem is caused because getWindow().setStatusBarColor() does not work well with the DrawerLayout. In order to keep your status bar translucent as well as being able to change its color, you have to follow the process below:
Add/modify the following theme in your v21/styles.xml file as below:
<style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
This is the theme that the standard DrawerLayout uses (assuming, of course, that you are using this theme in the activity that has the DrawerLayout). This will make your status bar translucent, as you already know.
Next, remove android:fitsSystemWindows="true" from the CoordinatorLayout in your app_bar_main.
Next, wherever you are changing the color of the toolbar/status bar, use drawerLayout.setStatusBarBackground(colorDrawable) using the same color you use for the toolbar (assuming, of course, that the reference to your DrawerLayout is called drawerLayout). Note that the drawerLayout.setStatusBarBackground() method takes a Drawable object, unlike the window.setStatusBarColor() method, which takes an int color, so you may have to convert your color to a drawable using something like this:
new ColorDrawable(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary))
This will make sure that your status bar is translucent as well as give it the ability to change colors. Hope you are able to get this to work.
As doc says here, FLAG_TRANSLUCENT_STATUS must not be set.
For this to take effect, the window must be drawing the system bar backgrounds with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS and FLAG_TRANSLUCENT_STATUS must not be set.
I do this in my app like this.
<style name="AppTheme" parent="Theme.AppCompat.Dark">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
the colorPrimary will set the status bar color, but only if you restart the activity.
so set that to a transparent black color, then in your code restart the activity. You can make more than one style in styles, with different colorPrimary values, then in your activity do this.
//onClick or condition statement here
setTheme(R.style.AppThemeLight);
setContentView(R.layout.activity_link_manager_light);
restart();
public void restart(){
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
I don't think you need to reset the contentview unless you are switching layouts as well, not sure you can try resetting it to the same layout if it's not working without it.
This definitely works for me but i've never tried to use a transparent value.
You can use this method to reset the entire app theme and switch to a new layout that has different colors hardcoded into it, just leave all the id's the same on the layout and in code you will get the right id as long as you reference the findViewByID AFTER you have setContentView to the proper layout that has the ID you call in it somewhere. The id's for each layout are different but you will always get the ID of the layout that is currently set with setContentView at the time you call findViewByID.
you can also save your current theme to a sharedpref file and use a switch to set the theme upon applaunch before setContentView is called (otherwise the statusbar color won't change)
consider this code. This is near the start of onCreate by the way
String Theme;
SaveData = getSharedPreferences(SaveFileName,0);
Theme = SaveData.getString("Theme","Default Theme");
switch(Theme){
case "Light Theme":
setTheme(R.style.AppThemeLight);
setContentView(R.layout.activity_link_manager_light);
ListTextViewID = R.id.AppListTextViewLight;
ListRowID = R.layout.app_list_item_light;
break;
The way i set the apptheme before i set the contentview is why the statusbar color change works.

Lollipop : draw behind statusBar with its color set to transparent

I have set my statusBar color to transparent for Lollipop only with the following line in my theme :
<item name="android:statusBarColor">#android:color/transparent</item>
Now I need to draw behind it, but I can't get any view draw behind it. I know how to do it with the windowTranslucentStatus property, but don't want to use this property since it will then ignore the color of the statusBar set to transparent.
Method #1:
To achieve a completely transparent status bar, you have to use statusBarColor, which is only available on API 21 and above. windowTranslucentStatus is available on API 19 and above, but it adds a tinted background for the status bar. However, setting windowTranslucentStatus does achieve one thing that changing statusBarColor to transparent does not: it sets the SYSTEM_UI_FLAG_LAYOUT_STABLE
and SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flags. The easiest way to get the same effect is to manually set these flags, which effectively disables the insets imposed by the Android layout system and leaves you to fend for yourself.
You call this line in your onCreate method:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
Be sure to also set the transparency in /res/values-v21/styles.xml:
<item name="android:statusBarColor">#android:color/transparent</item>
Or set the transparency programmatically:
getWindow().setStatusBarColor(Color.TRANSPARENT);
The good side to this approach is that the same layouts and designs can also be used on API 19 by trading out the transparent status bar for the tinted translucent status bar.
<item name="android:windowTranslucentStatus">true</item>
Method #2:
If you only need to paint a background image under your status bar, instead of positioning a view behind it, this can be done by simply setting the background of your activity's theme to the desired image and setting the status bar transparency as shown in method #1. This was the method I used to create the screenshots for the Android Police article from a few months ago.
Method #3:
If you've got to ignore the standard system insets for some layouts while keeping them working in others, the only viable way to do it is to work with the often linked ScrimInsetsFrameLayout class. Of course, some of the things done in that class aren't necessary for all scenarios. For example, if you don't plan to use the synthetic status bar overlay, simply comment out everything in the init() method and don't bother adding anything to the attrs.xml file. I've seen this approach work, but I think you'll find that it brings some other implications that may be a lot of work to get around.
I also saw that you're opposed to wrapping multiple layouts. In the case of wrapping one layout inside of another, where both have match_parent for height and width, the performance implications are too trivial to worry about. Regardless, you can avoid that situation entirely by changing the class it extends from FrameLayout to any other type of Layout class you like. It will work just fine.
This worked for my case
// Create/Set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Check if the version of Android is Lollipop or higher
if (Build.VERSION.SDK_INT >= 21) {
// Set the status bar to dark-semi-transparentish
getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// Set paddingTop of toolbar to height of status bar.
// Fixes statusbar covers toolbar issue
toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
}
// A method to find height of the status bar
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
For more information about working with statusBars: youtube.com/watch?v=_mGDMVRO3iE
Try this theme
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="colorPrimaryDark">#android:color/transparent</item>
<item name="colorPrimary">#color/md_blue_200</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
Be sure that, your layout set
android:fitsSystemWindows="false"
Instead of
<item name="android:statusBarColor">#android:color/transparent</item>
Use the following:
<item name="android:windowTranslucentStatus">true</item>
And make sure to remove the top padding (which is added by default) on your 'MainActivity' layout.
Note that this does not make the status bar fully transparent, and there will still be a "faded black" overlay over your status bar.
The solution from Cody Toombs almost did the trick for me. I'm not sure if this is Xamarin related or not, but I now have an acceptable solution:
This is my setup:
I have an Android project where I have referenced the Android.Support v4 and v7 packages. I have two styles defined:
values/styles.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<style name="MyStyle" parent="#style/Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>
values-v21/styles.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<resources>
<style name="MyStyle" parent="#style/Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
</resources>
AndroidManifest targets "MyStyle":
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.agn.test.test">
<uses-sdk android:minSdkVersion="10" />
<application android:allowBackup="true" android:icon="#mipmap/icon" android:label="#string/app_name" android:theme="#style/MyStyle">
</application>
</manifest>
And finally the code in the Main Activity:
[Activity (Label = "Test", MainLauncher = true, Icon = "#mipmap/icon")]
public class MainActivity : Activity
{
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
SetContentView (Resource.Layout.Main);
//Resource.Layout.Main is just a regular layout, no additional flags. Make sure there is something in there like an imageView, so that you can see the overlay.
var uiOptions = (int)Window.DecorView.SystemUiVisibility;
uiOptions ^= (int)SystemUiFlags.LayoutStable;
uiOptions ^= (int)SystemUiFlags.LayoutFullscreen;
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds);
}
}
Notice that I set DrawsSystemBarBackgrounds flag, this makes all the difference
Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds);
I spent a lot of time getting it right, too much time in fact. Hopefully this answer helps anyone trying to achieve the same thing.
#Cody Toombs's answer lead to an issue that brings the layout behind the navigation bar. So what I found is using this solution given by #Kriti
here is the Kotlin code snippet for the same:
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true)
}
if (Build.VERSION.SDK_INT >= 19) {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false)
getWindow().setStatusBarColor(Color.TRANSPARENT)
}
private fun setWindowFlag(activity: Activity, bits: Int, on: Boolean) {
val win: Window = activity.getWindow()
val winParams: WindowManager.LayoutParams = win.getAttributes()
if (on) {
winParams.flags = winParams.flags or bits
} else {
winParams.flags = winParams.flags and bits.inv()
}
win.setAttributes(winParams)
}
You also need to add
android:fitsSystemWindows="false"
root view of your layout.
I had the same problem so i create ImageView that draw behind status bar API 19+
Set custom image behind Status Bar gist.github.com
public static void setTransparent(Activity activity, int imageRes) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return;
}
// set flags
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
} else {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
// get root content of system window
//ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
// rootView.setFitsSystemWindows(true);
// rootView.setClipToPadding(true);
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
if (contentView.getChildCount() > 1) {
contentView.removeViewAt(1);
}
// get status bar height
int res = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
int height = 0;
if (res != 0)
height = activity.getResources().getDimensionPixelSize(res);
// create new imageview and set resource id
ImageView image = new ImageView(activity);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
image.setLayoutParams(params);
image.setImageResource(imageRes);
image.setScaleType(ScaleType.MATRIX);
// add image view to content view
contentView.addView(image);
// rootView.setFitsSystemWindows(true);
}
You can use ScrimInsetFrameLayout
https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
android:fitsSystemWindows="true" should set on scrim layout!
I will be adding some more information here. The latest Android developments have made it pretty easy to handle a lot of cases in status bar. Following are my observations from the styles.xml
Background color: for SDK 21+, as a lot of answers mentioned,<item name="android:windowTranslucentStatus">true</item> will make the status bar transparent and show in front of UI. Your Activity will take the whole space of the top.
Background color: again,for SDK 21+, <item name="android:statusBarColor">#color/your_color</item> will simply give a color to your status bar, without affecting anything else.
However, in later devices (Android M/+), the icons started coming in different shades. The OS can give a darker shade of gray to the icons for SDK 23/+ , if you override your styles.xml file in values-23 folder and add <item name="android:windowLightStatusBar">true</item>.
This way, you will be providing your user with a more visible status bar, if your status bar has a light color( think of how a lot of google apps have light background yet the icons are visible there in a greyish color).
I would suggest you to use this, if you are giving color to your status bar via point #2
In the most recent devices, SDK 29/+ comes with a system wide light and dark theme, controllable by the user. As devs, we are also supposed to override our style file in a new values-night folder, to give user 2 different experiences.
Here again, I have found the point #2 to be effective in providing the "background color to status bar". But system was not changing the color of status bar icons for my app. since my day version of style consisted of lighter theme, this means that users will suffer from low visibility ( white icons on lighter background)
This problem can be solved by using the point #3 approach or by overriding style file in values-29 folder and using a newer api <item name="android:enforceStatusBarContrast">true</item> . This will automatically enforce the grayish tint to icons, if your background color is too light.
With Android Studio 1.4, the template project with boiler plate code sets Overlay theme on your AppbarLayout and/or Toolbar. They are also set to be rendered behind the status bar by fitSystemWindow attribute = true. This will cause only toolbar to be rendered directly below the status bar and everything else will rendered beneath the toolbar. So the solutions provided above won't work on their own. You will have to make the following changes.
Remove the Overlay theme or change it to non overlay theme for the toolbar.
Put the following code in your styles-21.xml file.
#android:color/transparent
Assign this theme to the activity containing the navigation drawer in
the AndroidManifest.xml file.
This will make the Navigation drawer to render behind the transparent status bar.
Similar to some of the solutions posted, but in my case I did the status bar transparent and fix the position of the action bar with some negative margin
if (Build.VERSION.SDK_INT >= 21) {
getWindow().setStatusBarColor(Color.TRANSPARENT);
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
lp.setMargins(0, -getStatusBarHeight(), 0, 0);
}
And I used in the toolbar and the root view
android:fitsSystemWindows="true"
There is good library StatusBarUtil from #laobie that help to easily draw image in the StatusBar.
Just add in your build.gradle:
compile 'com.jaeger.statusbarutil:library:1.4.0'
Then in the Activity set
StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View viewNeedOffset)
In the layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/white"
android:orientation="vertical">
<ImageView
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:src="#drawable/toolbar_bg"/>
<android.support.design.widget.CoordinatorLayout
android:id="#+id/view_need_offset"
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"
android:background="#android:color/transparent"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- Your layout code -->
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>
For more info download demo or clone from github page and play with all feature.
Note: Support KitKat and above.
Hope that helps somebody else!
All you need to do is set these properties in your theme
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
The accepted answer worked for me using a CollapsingToolbarLayout. It's important to note though, that setSytstemUiVisibility() overrides any previous calls to that function. So if you're using that function somewhere else for the same view, you need to include the View.SYSTEM_UI_FLAG_LAYOUT_STABLE and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flags, or they will be overridden with the new call.
This was the case for me, and once I added the two flags to the other place I was making a call to setSystemUiVisibility(), the accepted answer worked perfectly.
Here is the theme I use to accomplish this:
<style name="AppTheme" parent="#android:style/Theme.NoTitleBar">
<!-- Default Background Screen -->
<item name="android:background">#color/default_blue</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
The Right solution is to Change a property in XML under your Activity tag to below style. It just works
android:theme="#style/Theme.AppCompat.Light.NoActionBar"

Android Navigation Drawer and windowActionBarOverlay = true

I'm trying to implement the new Android Navigation Drawer in my application. I have created a BaseActivity.java that handles the Drawer setup and listeners, and I have two subactivities that extend this base class. On the second activity, I plan to use a different action bar style, using the following attrs:
<item name="android:windowActionBarOverlay">true</item>
<item name="android:background">#android:color/transparent</item>
to make the action bar transparent, and make content richer, as there is a picture header in my layout.
I've achieved just that, but now the problem is, that because the content is expanding to take advantage of the extra space of using the ActionBar as overlay, the Navigation Drawer itself is expanding too and it overlaps the ActionBar, creating a pretty awful looking layout:
What I'd like to have done, is the actual content (frame layout that will be populated with a fragment) to take up the extra space, but have the nav drawer still go underneath the action bar, similar to the Play Music App:
Any ideas on what I can do to make that happen?
EDIT So, as per Ahmad's assistance I set the marginTop on the ListView only. Here's the layout:
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_marginTop="?android:attr/actionBarSize"
<!-- This was added after seeing the crazy effect, but does nothing -->
android:layout_marginBottom="0dp"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
android:layout_width="240dp"
android:layout_height="fill_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:background="?attr/listviewBackground"
/>
And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.
Not sure what's causing it :(
And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.
If you set your ListView gravity to start|bottom it solves your problem. No additional margin is added at the bottom. Looks like the DrawerLayout default gravity is start|center
<ListView
android:id="#+id/left_drawer"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start|bottom"/>
In case anyone is interested in another take to this question. Here's what happened.
I tried setting only the margin to the top of the list view like this:
android:layout_marginTop="?android:attr/actionBarSize"
But as mentioned on the edited question, that had a weird behaviour where there was also a margin on the bottom despite not being set on the layout resource file.
So, I was looking closely at the Play Music App and noticed that it's not actually a margin, but rather some padding, and additionally they are using a custom background that fills the space specified by the padding with a transparent color.
Here's what I did:
Set Padding at the top of the ListView, rather than margin:
android:paddingTop="?android:attr/actionBarSize"
As said before, it's important to not hard code the dimensions as they vary per device.
Create a custom drawable that has a top part transparent, and then rest of a solid color:
It looks somehow like this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<solid android:color="#80000000" />
</shape>
</item>
<item android:top="#dimen/action_bar_default_height">
<shape
android:shape="rectangle">
<solid android:color="#color/light_gray" />
</shape>
</item>
Note that I tried to use ?android:attr/actionBarSize on the drawable, but that made the app force close. Instead, I searched through grepcode and found a few dimen files with different sizes for the action bar, so I added those to my own project's dimen files.
For values: 48dp
For values-land: 40dp
For values-sw600dp: 56dp
And after that, I think I looks great, notice on the screenshot how the listview and the actionbar don't overlap, and the transparent part of the listview is just the right size.
Hope that helps anyone who was wondering how to achieve this.
You can set a margin at the top of your layout, so that the content draws itself below the ActionBar.
Just add this in your parent layout:
android:layout_marginTop="?android:attr/actionBarSize"
The attribute actionBarSize refers to, like you would have already guessed, to the size of the ActionBar. You can't set an absolute value as a margin, since the ActionBar does not always have the same size across all Android devices (It's bigger on tablets, smaller on handset devices).
Edit:
Set the margin to the ListView.
<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/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/left_drawer"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
The Google Music app does the same:
I solved this problem using paddingTop:
<FrameLayout
android:id="#+id/menu_frame"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:paddingTop="?attr/actionBarSize" >
<ListView
android:id="#+id/left_drawer_list"
android:layout_width="240dp"
android:layout_height="match_parent" />
</FrameLayout>
Hope that helps
I have created a working demo following the above guide and tested on 2.x to 5.x
You can clone from Github
The important thing to play around is in Main Activity
toolbar = (Toolbar) findViewById(R.id.toolbar);
res = this.getResources();
this.setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
findViewById(R.id.linearLayout);
scrimInsetsFrameLayout.setOnInsetsCallback(this);
}
and the call back
#Override
public void onInsetsChanged(Rect insets) {
Toolbar toolbar = this.toolbar;
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
toolbar.getLayoutParams();
lp.topMargin = insets.top;
int top = insets.top;
insets.top += toolbar.getHeight();
toolbar.setLayoutParams(lp);
insets.top = top; // revert
}
Absolutely the Theme for V21 does the magic
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- API 21 theme customizations can go here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/accent_material_light</item>
<item name="windowActionModeOverlay">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
</style>

Categories

Resources