How to draw layout with views under system bars? - android

I have to make layout, where top of the layout should be drawn under SystemBars. (min API level for this app is 22)
I set these flags to achieve that. In other activities I can draw whole fragment with views under SystemBars, but here I cant do it.
I used this code to allow layout to be drawn under SystemBars
window.apply {
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
statusBarColor = resources.getColor(android.R.color.transparent)
navigationBarColor = resources.getColor(android.R.color.transparent)
setBackgroundDrawable(background)
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
This is result in app:
I need to draw that grey area under system bar.
Update:
#Redman solution worked only partially.
Now I can draw under StatusBar but also I can draw under software buttons (navigationButtons) as you can see at screen below. Is there any way how to allow layout to be drawn under SystemBars but do not allow it under navigationButtons? Because that code what I've posted works for different fragments in app. But in other fragments I don't have ImageView as a part of ToolBar. If you have just ToolBar with for example 2-color gradient background and some backButton + SearchView, it is working fine. But as I add ImageView, ImageView will not "slide" under top SystemBar(aka StatusBar). Even in image above you can clearly see that green color (it's ToolBar background drawn under StatusBar). But ImageView is not allowed to be drawn under that bar.
The only way how to achieve that was with that special line of code
window.apply {
setFlags( WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
}
but this line also allowed to draw layout content under NavigationButtons (which is an issue).

In your Activity Theme add these properties
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
and in parent layout add property
android:fitsSystemWindows="true"
Edit
Try this to do it programmatically, it should work above on devices having kitkat and above
window.apply {
setFlags( WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
}

use toolbar view in your xml file. See below example
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="#dimen/height_50dp"
android:background="#f1f1f1">
\\define your any element here. Like back arrow or title
</android.support.v7.widget.Toolbar>

All you need to do is set these properties in your theme:
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
Your activity / container layout you wish to have a transparent status bar needs this property set:
android:fitsSystemWindows="true"
It is generally not possible to perform this for sure on pre-kitkat, looks like you can do it but some strange code makes it so.
EDIT: I would recommend this lib: https://github.com/jgilfelt/SystemBarTint for lots of pre-lollipop status bar color control.
Well after much deliberation I've learned that the answer to totally disabling the translucency or any color placed on the status bar and navigation bar for lollipop is to set this flag on the window:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow(); // in Activity's onCreate() for instance
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}

How about this:
Window window = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this, R.color.primary_dark));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int flags = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
window.addFlags(flags);
}
This should make Only StatusBar transparent.
If this didn't help, try adding:
<item name="android:windowTranslucentStatus">true</item>
To the Activity styles code in styles.xml.

Related

Can't set StatusBar color with setStatusBarColor if FLAG_LAYOUT_NO_LIMITS is used

I'm trying to draw a layout behind the NavigationBar. To do this I set FLAG_LAYOUT_NO_LIMITS as follows:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
This indeed causes the layout to be drawn behind the NavigationBar, but it also sets the StatusBar background color to white/transparent.
Changing the StatusBar color using getWindow().setStatusBarColor(Color.RED); has no effect.
I'm all the work dynamically and can't use and styling .xml files.
Is this a known behavior of FLAG_LAYOUT_NO_LIMITS?
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
Also check this

Android closing full screen view at the bottom is shunted off the screen

I have a screen with a bottom toolbar aligned using the following styling
<style name="BottomToolbar" >
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:background">#color/WHITE</item>
<item name="android:layout_gravity">bottom</item>
<item name="android:layout_alignParentBottom">true</item>
<item name="android:minHeight">?attr/actionBarSize</item>
</style>
When I first enter my screen the toolbar is nicely aligned to the bottom of the screen.
However, If I go to full screen mode (which hides the toolbar) and then return to normal mode (which re-displays the toolbar) the toolbar is now placed slightly off the screen. It looks as if its shifted down the amount of the status bar that is hidden in full screen mode.
If I background my app and then foreground it, the bottom toolbar is rendered correctly.
I have a bar at the top of the screen (instead of an appBar) and that is rendered in the correct place. I can not work out why it is misplacing the bottom toolbar.
Its as if when it is determining the bottom of the parent it is not adjusting for the fact its not full screen height anymore.
What I have tried
I have tried setting "fitsSystemWindows="true"" on my toolbar when exiting full screen mode but that doesn't make a difference.
I have tried setting the toolbar to INVISIBLE rather than GONE when hiding it but that makes no difference.
EDIT 1 - Added Code snippet of how I go into and out of full screen
I go into full screen using the following
getActivity().getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
I exit full screen by using the following code
getActivity().getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
EDIT 2 - View is not shoved off the bottom, its height is too small
It appears that the bottom view is not shoved off the bottom of the screen, its height is shrunk and smaller than it should be.
The bottom view is a LinearLayout with its height set to "wrap_content" but it appears the height is not calculated correctly as its shorter than its contents and hence the bottom of its contents are cut off.
Edit 3 - devices the issues presents on
Further investigation showed the issue only presents on devices which do not have the on screen navigation bar. For example the issue is on my Samsung 10" Tablet but not on my Nexus 5x.
If I remove the following flag the issue appears to be fixed
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
The Google doc for this flag is "When using other layout flags, we would like a stable view of the content insets given to fitSystemWindows(Rect)."
https://developer.android.com/reference/android/view/View.html
The docs say
"You may also need to use SYSTEM_UI_FLAG_LAYOUT_STABLE to help your app maintain a stable layout." (https://developer.android.com/training/system-ui/status.html) and
"It's good practice to include other system UI flags (such as SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION and SYSTEM_UI_FLAG_LAYOUT_STABLE) to keep the content from resizing when the system bars hide and show." (https://developer.android.com/training/system-ui/immersive.html)
I'm getting same issue. I also searched on google but not getting solution.
I have apply 100 milliseconds delay on onBackPressed() because I have used setSystemUiVisibility but It is taking time.
Issue - Fragment is calling before setSystemUiVisibility because setSystemUiVisibility is taking time so we need to set delay on back press.
public static void hideToolbarFoProfile(Context mContext) {
Activity mActivity = (Activity) mContext;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window w = Objects.requireNonNull(mActivity).getWindow();
w.getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
((MainActivity) Objects.requireNonNull(mActivity)).toolbar.setVisibility(View.GONE);
}
public static void showToolbarFoProfile(Context mContext) {
Activity mActivity = (Activity) mContext;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window w = Objects.requireNonNull(mActivity).getWindow();
w.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
w.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
}
((MainActivity) Objects.requireNonNull(mActivity)).toolbar.setVisibility(View.VISIBLE);
}
new Handler().postDelayed(() -> {
Objects.requireNonNull(getActivity()).onBackPressed();
}, 100);
My problem:
I exit from a fullscreen activity to a Dark Action theme activity.
I pressed back button on the soft keyboard to go back to fullscreen activity.
The views in the bottom were getting cut off suddenly.
I solved this by overriding onBackPressed() method and restarting my Activity:
#Override
public void onBackPressed() {
startActivity(new Intent(getApplicationContext(), YourActivityHere.class));
}
This should recreate the activity. It is a good hack if you can apply.

Customize Statusbar - Android

I am creating an application with some Activities. I want to change the status bar color and status bar icon colors which should look like the following image.
.
Is it possible to change? I am able to change the background color using the following code.
if (android.os.Build.VERSION.SDK_INT >= 21)
{
Window w = getWindow(); // in Activity's onCreate() for instance
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
w.setStatusBarColor(getResources().getColor(R.color.white_background_text));
}
Above code is working fine. Now I want to change the Wi-Fi icon, network icon, battery and time. Is it possible to do?
From another answer
Yes it's possible to change it to gray (no custom colors) but this only works from API 23 and above you only need to add this in your values-v23/styles.xml
<item name="android:windowLightStatusBar">true</item>

Translucent/Tansparent status bar and navigation bar

I would like to have the statusbar and the navigationbar Translucent on my Main activity, while all the other activities use the Material Design.
What I got so far is this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
But the result is:
I even tried to set the color to transparent:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(getResources().getColor(android.R.color.transparent));
window.setNavigationBarColor(getResources().getColor(android.R.color.transparent));
}
But I don't get the graduated shading I'm looking for to make the navigation buttons and the icons on the status bar visible:
Ideas?
I went around the problem.
I created a drawable that simulates the shade I was looking for and put it as wallpaper, while making the status bar and navigation bar transparent:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = this.getWindow();
Drawable background = this.getResources().getDrawable(R.drawable.background);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(getResources().getColor(android.R.color.transparent));
window.setNavigationBarColor(getResources().getColor(android.R.color.transparent));
window.setBackgroundDrawable(background);
}
Here's the result:
From Android Lollipop it is fully translucent, without any shade. So you should do a color like #33000000 to get a shade in the statusbar.
Edit
I think you can only set a color for the statusbar. But you can add an ImageView with a gradient drawable and only show it when you're on lollipop. The status bar is 25dp high. I think there is also an attribute for this, but I don't know it. This way you simulate a gradient in the statusbar.

Android statusbar overlay with ActionBar

I know that I can make the ActionBar overlay using requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY)
and can toggle/show the status bar in my screen (by switching between FLAG_FULLSCREEN and FLAG_FORCE_NOT_FULLSCREEN).
This works great. However, I don't want my layout moving when I toggle the status bar.
I know that I can make the status bar "overlay" (albeit not transparently) the content using:
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
This works also great, except for the (expected) consequence that, when using an ActionBar, the ActionBar gets half cut off - half of it is under the status bar basically.
So I am wondering, is there a way to "move the ActionBar down" by the status bar's height in this case?
I know that in worse case, I can do this with a custom view that lives within the layout, but I rather not do this (want to benefit from the ActionBar).
thanks!
so apparently, you can do this in Jellybean. google includes two examples in the api docs. here is a link: http://developer.android.com/reference/android/view/View.html#setSystemUiVisibility%28int%29
summary:
use setSystemUiVisibility on a view to toggle visibility (on jellybean+).
It's not perfect, but this is how I have achieved what you want:
In onCreate:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Then:
private void hideStatusBar() {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
}
private void showStatusBar() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
I also have a style on the activity with the following:
<style name="readingStyle" parent="#style/Theme.Sherlock">
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
</style>
Your activity will shift down when the status bar shows, but I don't think it's too noticeable.
Why you dont make it in the Manifest
android:theme="#android:style/Theme.Black.NoTitleBar"
than you have no statusbar and more space for the Actionbar??
Put this method in onCreate() method activity:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
refer: link

Categories

Resources