I'm trying to achieve the effect shown here: http://www.youtube.com/watch?v=6QHkv-bSlds&t=15m48s by Nick and the boys. I can get the action bar to be overlayed, but cannot figure out how to extend this to the status bar. I would also like to know how they managed the transparent black background behind the navigation bar (but this isn't as crucial).
Any help / advice would be greatly appreciated as I currently have no idea how this is done (and am starting to worry it may just be an image rather than an actual implementation).
Edit: i know how to make the bars fully transparent (thats the easy part)! I dont know how to extend the actionbar background to appear behind the now transluscent status bar
I had the same question and found this library: https://github.com/jgilfelt/SystemBarTint
Have a look at line 300 in:
https://github.com/jgilfelt/SystemBarTint/blob/master/library/src/com/readystatesoftware/systembartint/SystemBarTintManager.java
setupStatusBarView() Adds a view to the window's decor. This allows you to later set a color/drawable to this view.
If using the SystemBarTint library, the following will allow you to force the status bar to a specified color, which you can then match to your action bar's background:
SystemBarTintManager tintManager = new SystemBarTintManager(this);
tintManager.setStatusBarTintEnabled(true);
tintManager.setStatusBarTintColor(Color.parseColor("#DD000000"));
In this case you would set your action bar's background to: #DD000000
As described in the Android 4.4 APIs:
You can now make the system bars partially translucent with new themes, Theme.Holo.NoActionBar.TranslucentDecor and Theme.Holo.Light.NoActionBar.TranslucentDecor. By enabling translucent system bars, your layout will fill the area behind the system bars, so you must also enable fitsSystemWindows for the portion of your layout that should not be covered by the system bars.
If you're creating a custom theme, set one of these themes as the parent theme or include the windowTranslucentNavigation and windowTranslucentStatus style properties in your theme.
In your case (where you want the ActionBar), the second option - including the two new properties into your theme - will give you a translucent Navigation and Status bar.
They are using the new Translucent system bars feature (on Android 4.4 and up).
Translucent system bars
You can now make the system bars partially translucent with new
themes, Theme.Holo.NoActionBar.TranslucentDecor and
Theme.Holo.Light.NoActionBar.TranslucentDecor. By enabling translucent
system bars, your layout will fill the area behind the system bars, so
you must also enable fitsSystemWindows for the portion of your layout
that should not be covered by the system bars.
If you're creating a custom theme, set one of these themes as the
parent theme or include the windowTranslucentNavigation and
windowTranslucentStatus style properties in your theme.
Related
I'm trying to add the edge-to-edge stuff for the gesture navigation bar to the Tip Time app from Google. I added the transparent navigationBarColor XML tag to themes.xml as well as the following code to the onCreate() function of MainActivity.kt:
This was directly copy-pasted from the documentation. Android Studio says that "it cannot find a parameter with this name" for each of the three margins. I noticed that changing the parenthesis right after <ViewGroup.MarginLayoutParams> to curly braces fixes the compiler error. Maybe the documentation is just wrong?
Anyways, even after fixing that, the app still doesn't look right:
As you can see, the entire view gets shifted up slightly and the "Cost of Service" TextView is partially cut-off by the app bar. What would I need to change to implement the system/navigation bar insets for edge-to-edge content so the UI looks nice? Also, as a side-question, how can I change the dark blue color of the system status bar to match the color of the app bar so that they look blended?
As per documentation for edge to edge contents:
Draw behind the status bar if it makes sense for your content and
layout, such as in the case of full-width imagery. To do this, use
APIs such as AppBarLayout, which defines an app bar pinned to the top
of the screen.
So, while handing the window insets (especially the top one), you can't use the default ActionBar, instead you need to customize that with AppBarLayout and ToolBar, and to make it act as the ActionBar, use setSupportActionBar(), and a NoActionBar app theme; it'd be <style name="Theme.TipTime" parent="Theme.MaterialComponents.DayNight.NoActionBar"> in the shared repo.
the entire view gets shifted up slightly and the "Cost of Service" text field is partially cut-off by the app bar.
The reason that the sample uses the default ActionBar instead of a customized one; when it comes to handle the top window insets, it won't affect the default ActionBar; notice that you pass in the activity's root layout to setOnApplyWindowInsetsListener callback, and as the ActionBar is not a part of the activity, it won't be affected. Therefore the activity is shifted up behind the ActionBar when the top inset is removed. So, to solve this you have either to totally remove the default ActionBar or to use a custom toolbar instead.
Also, as a side-question, how can I change the dark blue color of the system status bar to match the color of the app bar so that they look blended?
Use a transparent status bar color in the app's theme:
<item name="android:statusBarColor" tools:targetApi="l">#android:color/transparent</item>
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)
I am a noob on android graphics and I would like to change the appearance of a seek bar without creating a completely new custom view. I noticed that if I change the android:theme="#android:style/theme..." of the activity in the android manifest the style of the seek bar change. But what if I want a particular style for the seek bar only and keep unchanged the style of the activity? How can I see all possible precompiled styles?
Obviously, the question is for all other views also...
Setting the navigation bar color to something other than black only plays well with material design if you set it to transparent (or the same color as the window background) and the content is not scrollable.
<item name="android:navigationBarColor">#android:color/transparent</item>
If the navigation bar has another color or if the content is scrollable, the ink just gets cut off when reaching the bar like in the picture:
I would like to set an elevation on the navigation bar so that it casts a shadow and it becomes clear that it's another layer. Is this possible?
According to Google I/O Android talks, all shadows are generated by some light source, which provides shadows under elements, not above them. Then, Navigation Bar should have no visible shadow.
Maybe, the only solution of your problem is to use additional drawable to imitate shadow.
Since Android 4.4 was introduced I had this big question about translucent notification and navigation bar:
How do you make a custom theme so that the notification bar is the same color as the action bar as well as the navigation bar be the same color that the current activity is?
A good example of this is the Trello app:
And:
Even if you open a navigation drawer, the navigation bar still retains its color. How does one achieve this?
You can use the new (as of 4.4) Theme.Holo.NoActionBar.TranslucentDecor or Theme.Holo.Light.NoActionBar.TranslucentDecor themes. Or you can set windowTranslucentNavigation in your theme. You'll also want to fill the area behind the system bars by setting fitsSystemWindows to true in your layout.
More info in the Android 4.4 APIs changes document