I am facing a rather annoying issue on Android.
I have an activity which has 3 fragments inside, all fragments fill the screen. The designer was very specific about the look of the statusbar on the devices and this is what he requested:
First Fragment: Transparent Status Bar with White Text and a background image that also falls behind the status bar.
Second Fragment: Transparent Status Bar with Dark Text and a background image that also falls behind the status bar.
Third Fragment: Status Bar with Custom Color and Dark Text that doesn't let content get beneath it.
How on earth do I do this, considering that they all must be fragments in a single activity and I've played with flags like WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, windowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR, decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN, decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
but no combination results in a good behavior. Literally I can't get it to have the requested look. Sometimes, one fragment has a good status bar, but if I go back, the status bar stops working properly on the previous fragment and so on.
Can somebody please teach me how can I achieve this.
P.S. I can't believe Android is such a damn disappointing mess of an operating system sometimes. Handling the look of the status bar should have been an one-liner, easy to use, just like on iOS....
Just use it in every fragment
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.BLUE);
}
I'm doing it in that way:
window.statusBarColor = ContextCompat.getColor(this, R.color.white)
remember that you have to change the color of icons at status bar also ; )
window.decorView.windowInsetsController?.setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS)
I'm using navigation component and at Activity I've got a navigation change listener who provide me current fragment's id.
Related
I'm confused that in different documents, Navigation Bar refers to different controls, but here, it is the Android feature, which provides navigation controls besides the hardware buttons.
I hope to get the height of this bar wide code.
After digging solutions about hiding the bar permanently, I reaized it's not possible to do so (which is the most desiered way of sovling the problem), please do correct me if the bar can be hide permanently!!! I attached the code here I used to hide the bar, but whenever I tap the screen, the bar re-appear.
Instead, can I get the height of the bottom software navigation bar on Android so that I can adjust the position of page elements accordingly?
(What is more annyoing is that some Android devices allow user the manually show and hide the bar by clicking an arrow button on the bar.)
//In OnCreate of MainActivity.cs,
int uiOptions = (int)Window.DecorView.SystemUiVisibility;
uiOptions |= (int)SystemUiFlags.HideNavigation;
Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;
//In some topics, people said to add some more SystemUiFlags, such as IMMERSIVE_STICKY, LAYOUT_FULLSCREEN, but with those, the bar cannot be hidden.
Strangly, DeviceDisplay.MainDisplayInfo.Height includes the height of the Navigation bar, otherwise I don't need to do what described above. Is there a way of detecting screen height without the software navigation bar?
Thanks so much for any help on this.
PS: Instead of getting the height, can I at least detect if the software navigation bar is on / shown?!
Now I know I can detect if the device has hard navigation keys with ViewConfiguration.Get(Android.App.Application.Context).HasPermanentMenuKey, this is useful, but I still can't detect if the soft navigation bar is on or not.
About get Navigation bar height in xamarin.form, you can try to use:
TypedArray styledAttributes = this.Theme.ObtainStyledAttributes(new int[] {Android.Resource.Attribute.ActionBarSize });
var actionbarHeight = (int)styledAttributes.GetDimension(0, 0);
styledAttributes.Recycle();
Console.WriteLine("the height is {0}",actionbarHeight);
I'm using a Unity/Vuforia view in an app, when showing a native Snackbar the whole content shrinks for a bit and stays that way.
My first thought was that it had something to do with the fact that unity/Vuforia sets the activity as 'Fullscreen', disabling that did not work as the issue still remains.
The Content before the snackbar has been shown
After the snackbar
I noticed it has the same height of a Toolbar or the NavigationBars at the bottom. When playing around with the options to hide the Navigation Bars I noticed the changes won't stay. When trying to hide it all, it hides for a second and then after a 200 milliseconds show again.
I tried it with this code
window.decorView.apply {
// Hide both the navigation bar and the status bar.
// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as
// a general rule, you should design your app to hide the status bar whenever you
// hide the navigation bar.
systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
The way I fixed it was by enabling the Fullscreen option in Vuforia, it was not what we desired, but it was the quickest solution.
I am trying to make this ui for a project, but alas, i am stuck at throwing way too many hacks to get even close to this.
Here's all that I have tried.
Window background is set to be the gradient, and then the bottom views have their own white background. Hate this because it's causing way too many draws
The spacing between the app bar and status becomes way too less if i use this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
w.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
Adding a custom Textview and setting title to "", seems to help center the title, but the font is way off.
I have added the code mDrawerToggle.setHomeAsUpIndicator(R.mipmap.hamburger); for changing the drawer toggle icon, but it's not reflecting at all.
I had to manually set the android:background="null" for the appbarlayout to set it to become transparent. Could not find a way to use the theme for the same!
Any tips are very very welcome!
I'm looking into a way where the status bar is completely transparent, not translucent and where the Navigation Bar is left untouched.
Closest I can get is to use the flag
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
but this draws behind the Navigation Bar as well.
The background is what is making this tricky, it is a subtle gradient, and when I set the status bar color to the start of the gradient, it looks almost right, but has a subtle line across the top of the screen.
Is there a good way to fit the activity to the window, only at the top but if there is a navigation bar at the bottom, leave it alone?
A good approach is Method One from this answer.
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>
I'm guessing you've tried this or something similar. If that's not working, make sure your root element is a FrameLayout.
Disclaimer:
This is complementary answer as the accepted answer is valid without deprecation > till API level 30 because the system
visibility flags are deprecated as of API level 30.
setDecorFitsSystemWindows() implements edge-to-edge to your app (i.e. the app will be expanding its content to extend across the entire screen to cover both the system status & navigation bars)
And this can be implemented in the activity with:
WindowCompat.setDecorFitsSystemWindows(window, false)
Now the remaining part is to avoid the overlapping with the system navigation bar:
As per documentation:
You can address overlaps by reacting to insets, which specify which
parts of the screen intersect with system UI such as the navigation
bar or the status bar. Intersecting can mean simply being displayed
above the content, but it can also inform your app about system
gestures, too.
So, We need to handle the insets for API level 30+ to avoid the overlapping between the app and the bottom navigation bar:
/*
* Making the Navigation system bar not overlapping with the activity
*/
if (Build.VERSION.SDK_INT >= 30) {
// Root ViewGroup of my activity
val root = findViewById<ConstraintLayout>(R.id.root)
ViewCompat.setOnApplyWindowInsetsListener(root) { view, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
// Apply the insets as a margin to the view. Here the system is setting
// only the bottom, left, and right dimensions, but apply whichever insets are
// appropriate to your layout. You can also update the view padding
// if that's more appropriate.
view.layoutParams = (view.layoutParams as FrameLayout.LayoutParams).apply {
leftMargin = insets.left
bottomMargin = insets.bottom
rightMargin = insets.right
}
// Return CONSUMED if you don't want want the window insets to keep being
// passed down to descendant views.
WindowInsetsCompat.CONSUMED
}
}
Check documentation for more info.
Extra cent:
If you're going to use <item name="android:windowTranslucentStatus">true</item> for lower API levels, then you have to override the themes/styles in API-30; i.e. to have a res\values-v30\themes.xml with the default style (of course without windowTranslucentStatus)
There are some Android 4.4 applications in which the system's navigation bar is simultaneously dimmed and transparent. One example of this is the camera app on the Xperia Z1:
I've been trying to find a way to replicate this, and so far I have no problem setting up the navigation bar as translucent (by setting the style to android:Theme.Holo.NoActionBar.TranslucentDecor, for instance) or as dimmed:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE | decorView.getSystemUiVisibility();
decorView.setSystemUiVisibility(uiOptions);
The thing is, I can't seem to find a way to do both of them at the same time (i.e. simultaneously dimmed and transparent). It seems that whenever I define the app's style to use the transparent navigation bar, the dim flag stops having any effect.
I've tried a lot of different stuff with no results... Any suggestion? Thanks in advance for any answer.