I've searched the documentation but only found this:Link . Which is used to make the bar translucent ? What I'm trying to do is to make the status bar completely transparent (as shown in the image below) and make it backwards compatible for APK<19:
My styles.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:actionBarStyle">@style/ThemeActionBar</item>
<item name="android:windowActionBarOverlay">true</item>
<!-- Support library compatibility -->
<item name="actionBarStyle">@style/ThemeActionBar</item>
<item name="windowActionBarOverlay">true</item>
</style>
<style name="ThemeActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="android:background"> @null </item>
<!-- Support library compatibility -->
<item name="background">@null</item>
<item name="android:displayOptions"> showHome | useLogo</item>
<item name="displayOptions">showHome|useLogo</item>
</style>
</resources>
What I was able to do:
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:
// In Activity's onCreate() for instance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
No other theme-ing is necessary, it produces something like this:
You Can Use Below Code To Make Status Bar Transparent. See Images With red highlight which helps you to identify use of Below code
Kotlin code snippet for your android app
Step:1 Write down code in On create Method
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(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(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false)
window.statusBarColor = Color.TRANSPARENT
}
Step2: You Need SetWindowFlag method which describe in Below code.
private fun setWindowFlag(bits: Int, on: Boolean) {
val win = window
val winParams = win.attributes
if (on) {
winParams.flags = winParams.flags or bits
} else {
winParams.flags = winParams.flags and bits.inv()
}
win.attributes = winParams
}
Java code snippet for your android app:
Step1: Main Activity Code
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) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
Step2: SetWindowFlag Method
public static void setWindowFlag(Activity activity, final int bits, boolean on) {
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
Just add this line of code to your main java file:
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
);
Works for Android KitKat and above (For those who want to transparent the status bar and don't manipulate the NavigationBar, because all of these answers will transparent the NavigationBar too!)
The easiest way to achieve it:
Put these 3 lines of code in the styles.xml (v19)
-> if you don't know how to have this (v19), just write them in your default styles.xml
and then use alt + enter to automatically create it:
<item name="android:windowFullscreen">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:fitsSystemWindows">false</item>
And now, go to your MainActivity
Class and put this Method out of onCreate in the class:
public static void setWindowFlag(Activity activity, final int bits, boolean on) {
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
Then put this code in the onCreate
method of the Activity:
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) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
//make fully Android Transparent Status bar
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
That's it!
You can use the external library StatusBarUtil :
Add to your module level build.gradle
:
compile 'com.jaeger.statusbarutil:library:1.4.0'
Then you can use the following util for an Activity to make the status bar transparent:
StatusBarUtil.setTransparent(Activity activity)
Example:
Completely Transparent StatusBar and NavigationBar
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
transparentStatusAndNavigation();
}
private void transparentStatusAndNavigation() {
//make full transparent statusBar
if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
}
if (Build.VERSION.SDK_INT >= 19) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
getWindow().setNavigationBarColor(Color.TRANSPARENT);
}
}
private void setWindowFlag(final int bits, boolean on) {
Window win = getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
To draw your layout under statusbar:
values/styles.xml
<item name="android:windowTranslucentStatus">true</item>
values-v21/styles.xml
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>
Use CoordinatorLayout/DrawerLayout which already take care of the fitsSystemWindows parameter or create your own layout to like this:
public class FitsSystemWindowConstraintLayout extends ConstraintLayout {
private Drawable mStatusBarBackground;
private boolean mDrawStatusBarBackground;
private WindowInsetsCompat mLastInsets;
private Map<View, int[]> childsMargins = new HashMap<>();
public FitsSystemWindowConstraintLayout(Context context) {
this(context, null);
}
public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (ViewCompat.getFitsSystemWindows(this)) {
ViewCompat.setOnApplyWindowInsetsListener(this, new android.support.v4.view.OnApplyWindowInsetsListener() {
@Override
public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
FitsSystemWindowConstraintLayout layout = (FitsSystemWindowConstraintLayout) view;
layout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
return insets.consumeSystemWindowInsets();
}
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
TypedArray typedArray = context.obtainStyledAttributes(new int[]{android.R.attr.colorPrimaryDark});
try {
mStatusBarBackground = typedArray.getDrawable(0);
} finally {
typedArray.recycle();
}
} else {
mStatusBarBackground = null;
}
}
public void setChildInsets(WindowInsetsCompat insets, boolean draw) {
mLastInsets = insets;
mDrawStatusBarBackground = draw;
setWillNotDraw(!draw && getBackground() == null);
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
if (ViewCompat.getFitsSystemWindows(this)) {
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) child.getLayoutParams();
if (ViewCompat.getFitsSystemWindows(child)) {
ViewCompat.dispatchApplyWindowInsets(child, insets);
} else {
int[] childMargins = childsMargins.get(child);
if (childMargins == null) {
childMargins = new int[]{layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin};
childsMargins.put(child, childMargins);
}
if (layoutParams.leftToLeft == LayoutParams.PARENT_ID) {
layoutParams.leftMargin = childMargins[0] + insets.getSystemWindowInsetLeft();
}
if (layoutParams.topToTop == LayoutParams.PARENT_ID) {
layoutParams.topMargin = childMargins[1] + insets.getSystemWindowInsetTop();
}
if (layoutParams.rightToRight == LayoutParams.PARENT_ID) {
layoutParams.rightMargin = childMargins[2] + insets.getSystemWindowInsetRight();
}
if (layoutParams.bottomToBottom == LayoutParams.PARENT_ID) {
layoutParams.bottomMargin = childMargins[3] + insets.getSystemWindowInsetBottom();
}
}
}
}
}
requestLayout();
}
public void setStatusBarBackground(Drawable bg) {
mStatusBarBackground = bg;
invalidate();
}
public Drawable getStatusBarBackgroundDrawable() {
return mStatusBarBackground;
}
public void setStatusBarBackground(int resId) {
mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null;
invalidate();
}
public void setStatusBarBackgroundColor(@ColorInt int color) {
mStatusBarBackground = new ColorDrawable(color);
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDrawStatusBarBackground && mStatusBarBackground != null) {
int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
if (inset > 0) {
mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
mStatusBarBackground.draw(canvas);
}
}
}
}
main_activity.xml
<FitsSystemWindowConstraintLayout 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">
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/toolbar_background"
app:layout_constraintBottom_toBottomOf="@id/toolbar"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/transparent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Content"
android:textSize="48sp" />
</LinearLayout>
</FitsSystemWindowConstraintLayout>
Result:
Simple and crisp and works with almost all use cases (for API level 16 and above):
Use the following tag in your app theme to make the status bar transparent:
<item name="android:statusBarColor">@android:color/transparent</item>
And then use this code in your activity's onCreate method.
View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
That's all you need to do ;)
You can learn more from the developer documentation. I'd also recommend reading this blog post.
KOTLIN CODE :
val decorView = window.decorView
decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
Check my another answer here
Here is a extension in kotlin that do the trick:
fun Activity.setTransparentStatusBar() {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.statusBarColor = Color.TRANSPARENT
}
}
在顶部布局中使用android:fitsSystemWindows="false"
THERE ARE THREE STEPS:
1) Just use this code segment into your OnCreate method
// FullScreen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
If you're working on Fragment, you should put this code segment in your activity's OnCreate method.
2) Be sure to also set the transparency in /res/values-v21/styles.xml:
<item name="android:statusBarColor">@android:color/transparent</item>
Or you can set the transparency programmatically:
getWindow().setStatusBarColor(Color.TRANSPARENT);
3) In anyway you should add the code segment in styles.xml
<item name="android:windowTranslucentStatus">true</item>
NOTE: This method just works on API 21 and above.
For API > 23 with Day/Night support you can use the extension below. Important part to understand is that android:fitsSystemWindows="true"
uses padding to move within insets (like you would with a Toolbar). Therefore it does not make sense to place it at your root layout (except DrawerLayout, CoordinatorLayout, ... these use their own implementation).
<style name="Theme.YourApp.DayNight" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
<item name="android:windowLightStatusBar">@bool/isDayMode</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
<androidx.constraintlayout.widget.ConstraintLayout
...>
<com.google.android.material.appbar.MaterialToolbar
...
android:fitsSystemWindows="true">
</androidx.constraintlayout.widget.ConstraintLayout
fun Activity.transparentStatusBar() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
} else {
window.setDecorFitsSystemWindows(false)
}
}
Then call it like so:
class YourActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
transparentStatusBar()
}
}
Check these slides by Chris Banes: Becoming a master window fitter
Edit: If you have problems with content floating behind your navigation bar, use
// using Insetter
binding.yourViewHere.applySystemWindowInsetsToPadding(bottom = true)
I just found it here
Because it's already pass 6 years, and the default minSDKAPI is 21 (Lollipop) *CMIIW. Here is my way to conclude transparent status bar and not overlapping with navigation button:
fun setStatusBarTransparent(activity: Activity, view: View) {
activity.apply {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = ContextCompat.getColor(this, R.color.transparent)
WindowCompat.setDecorFitsSystemWindows(window, false)
ViewCompat.setOnApplyWindowInsetsListener(view) { root, windowInset ->
val inset = windowInset.getInsets(WindowInsetsCompat.Type.systemBars())
root.updateLayoutParams<ViewGroup.MarginLayoutParams> {
leftMargin = inset.left
bottomMargin = inset.bottom
rightMargin = inset.right
}
WindowInsetsCompat.CONSUMED
}
}
}
I put that function inside Object
class called UiUtils
so when I call that function in my activity (I using View Binding too). It'll look like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
UiUtils.setStatusBarTransparent(this, bind.root)
...
}
Hope my answer can help you guys :)
This is a simple way I found it after a lot of searches.
Step 1
in your theme put this item
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
Step 2
In main Activity
WindowCompat.setDecorFitsSystemWindows(window, false)
Very Important if u used BottomNavigationBar
in some devices, with API 30+ u will find system navigation bar overlap with bottom navigation bar if used it in your application.
this is solving for this problem.
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
}
}
Using this code in your XML, you will be able to see time bar in your activity:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
I found fiddling with styles.xml and activity to be too cumbersome hence created a common utility method which has below options set
Java
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
window.setStatusBarColor(Color.TRANSPARENT);
Kotlin DSL
activity.window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
statusBarColor = Color.TRANSPARENT
}
And that's all it took to achieve transparent status bar. Hope this helps.
<style name="Theme.Transparent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
</style>
Try the following code:
private static void setStatusBarTransparent(Activity activity) {
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);
}
}
This worked for me:
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">false</item>
<item name="android:windowTranslucentNavigation">false</item>
You can also view my example with animated avatar and animated text
Read my post on Medium
So lets me to explaine how it works. I created custom view implemented AppBarLayout.OnOffsetChangedListener . Inside HeadCollapsing Custom View i founded text and image view in AppBarLayout.
class HeadCollapsing(context: Context, attrs: AttributeSet?) :
FrameLayout(context, attrs), AppBarLayout.OnOffsetChangedListener {
private fun findViews() {
appBarLayout = findParentAppBarLayout()
avatarContainerView = findViewById(R.id.imgb_avatar_wrap)
titleToolbarText = findViewById<AppCompatTextView>(id)
}
private fun findParentAppBarLayout(): AppBarLayout {
val parent = this.parent
return parent as? AppBarLayout ?: if (parent.parent is AppBarLayout) {
parent.parent as AppBarLayout
} else {
throw IllegalStateException("Must be inside an AppBarLayout")
}
}
...
override fun onOffsetChanged(appBarLayout: AppBarLayout, offset:Int) {
...
//Calculate expanded percentage
val expandedPercentage = 1 - -offset / maxOffset
updateViews(expandedPercentage)
}
}
Then change views via calculated percentage. For example, how text view changing:
when {
inversePercentage < ABROAD -> {
titleToolbarText?.visibility = View.VISIBLE
titleTolbarTextSingle?.visibility = View.INVISIBLE
}
inversePercentage > ABROAD -> {
titleToolbarText?.visibility = View.INVISIBLE
titleTolbarTextSingle?.visibility = View.VISIBLE
titleTolbarTextSingle?.let {
animateShowText(it)
}
}
}
To detect when need image collapse animate created Pair object
private var cashCollapseState: kotlin.Pair<Int, Int>? = null
with states: TO_EXPANDED_STATE, TO_COLLAPSED_STATE, WAIT_FOR_SWITCH, SWITCHED
companion object {
const val ABROAD = 0.95f
const val TO_EXPANDED_STATE = 0
const val TO_COLLAPSED_STATE = 1
const val WAIT_FOR_SWITCH = 0
const val SWITCHED = 1
}
then cretaed animation for avatar swith state:
when {
cashCollapseState != null && cashCollapseState != state -> {
when (state.first) {
TO_EXPANDED_STATE -> {
// do calculates
}
TO_COLLAPSED_STATE -> {
ValueAnimator.ofFloat(avatarContainerView.translationX, translationX).apply {
addUpdateListener {
avatarContainerView.translationX = it.animatedValue as Float
}
duration = 350
(state.first == TO_COLLAPSED_STATE).apply {
if (this) interpolator = LinearInterpolator()
}
start()
}
//SWITCH STATE CASE
cashCollapseState = kotlin.Pair(state.first, SWITCHED)
}
else -> {
cashCollapseState = kotlin.Pair(state.first, WAIT_FOR_SWITCH)
}
All one need is to go into MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window g = getWindow();
g.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
setContentView(R.layout.activity_main);
}
in my case, i dont call at all "onCreate" (its a react native app and this can be fixes also by using the react-native StatusBar component) one can also use this:
override fun onStart() {
super.onStart()
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = Color.TRANSPARENT
}
While all the answers above circulate around the same fundamental idea and you can get it to work with simple layouts using one of the examples above. However I wanted to change the color of the background while using sliding 'full screen' (tab bar aside) fragment navigation and maintain regular navigation, tab and action bars.
After reading carefully an article by Anton Hadutski I had better understanding what is going on.
I have DrawerLayout
with ConstraintLayout
(ie container) which has Toolbar
, include for the main fragment and BottomNavigationView
.
Setting DrawerLayout
having fitsSystemWindows
to true isn't sufficient, you need to set both DrawerLayout
and ConstraintLayout
. Assuming transparent status bar, the status bar color is now the same as the background color of ConstraintLayout
.
However, the included fragment has still the status bar inset, so animating another 'full screen' fragment on top of with doesn't change the color of the status bar.
A bit of code from the referred article into Activity
's onCreate
:
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
insets.replaceSystemWindowInsets(
insets.systemWindowInsetLeft,
0,
insets.systemWindowInsetRight,
insets.systemWindowInsetBottom
)
}
And all is good, except now the Toolbar
doesn't address the status bar height. Some more referring to the article and we have a fully working solution:
val toolbar = findViewById<Toolbar>(R.id.my_toolbar)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.container)) { view, insets ->
val params = toolbar.layoutParams as ViewGroup.MarginLayoutParams
params.topMargin = insets.systemWindowInsetTop
toolbar.layoutParams = params
insets.replaceSystemWindowInsets(
insets.systemWindowInsetLeft,
0,
insets.systemWindowInsetRight,
insets.systemWindowInsetBottom
)
}
The main_activity.xml (please note that marginTop in Toolbar
is for preview purposes, it will be replaced by the code):
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
>
<androidx.constraintlayout.widget.ConstraintLayout 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/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/green"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="@id/container"
android:layout_marginTop="26dp"
android:background="@android:color/transparent"
...>
...
</androidx.appcompat.widget.Toolbar>
<include layout="@layout/content_main" />
...
</androidx.constraintlayout.widget.ConstraintLayout>
...
</androidx.drawerlayout.widget.DrawerLayout>
Here is the Kotlin Extension:
fun Activity.transparentStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.statusBarColor = Color.TRANSPARENT
} else
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
android:fitsSystemWindows="true"
only work on v21. We can set it in theme xml or in parent layout like LinearLayout
or in CoordinateLayout
. For below v21, We could not add this flag. Please create different values folder with different style.xml
file as per your need.
<item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
<!--<item name="android:windowLightStatusBar" tools:targetApi="m">true</item>-->
Dont use windowLightStatusBar
use instead statusBarColor = @android:color/transparent
add these lines into your Activity before the setContentView()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
add these 2 lines into your AppTheme
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
and last thing your minSdkVersion must b 19
minSdkVersion 19
in my case as I've a bottom tool bar I had a problem when testing the previous solutions, the android system buttons are covered with my bottom menu my solution is to add within the activity:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
// force full screen mode requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main_activity_container);
You can use this below code.
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(Color.TRANSPARENT);
Include this layout in your main layout.
toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbarNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:contentInsetEnd="0dp"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp">
<RelativeLayout
android:id="@+id/rlBackImageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/main_background2"> //add your color here
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/_40sdp"
android:layout_marginTop="@dimen/_16sdp"
android:orientation="horizontal">
<ImageView
android:id="@+id/toolbarIcon"
android:layout_width="@dimen/_30sdp"
android:layout_height="@dimen/_30sdp"
android:layout_gravity="center"
android:layout_marginStart="@dimen/_10sdp"
android:padding="@dimen/_5sdp"
android:src="@drawable/nav_icon" />
<TextView
android:id="@+id/txtTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/_30sdp"
android:fontFamily="@font/muli_semibold"
android:gravity="center"
android:textColor="#fff"
android:textSize="@dimen/_14ssp"
android:textStyle="bold"
tools:text="test Data" />
</LinearLayout>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
Note: You can replace SDP and SSP with dp and sp respectively.
This should work
// In Activity's onCreate() for instance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window w = getWindow();
w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
The following code will make your status bar along with the navigation bar transparent (note that this will make your layout a full screen layout like the layouts used in games):
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUI();
}
}
private void hideSystemUI() {
// Enables sticky immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE_STICKY.
// Or for regular immersive mode replace it with SYSTEM_UI_FLAG_IMMERSIVE
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN);
}
To learn more, visit this link.
The following code will create a fully transparent status bar:
package com.demo;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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) {
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
if (Build.VERSION.SDK_INT >= 21) {
setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
public static void setWindowFlag(Activity activity, final int bits, boolean on) {
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
if (on) {
winParams.flags |= bits;
} else {
winParams.flags &= ~bits;
}
win.setAttributes(winParams);
}
}
This solution is intended for those who want to have a completely transparent StatusBar and have the NavigationBar unaffected. Incredibly this sounds so simple that it has caused a headache to more than one, including me.
This is the final result I'm talking about
We are going to need only two functions, that I recommend to invoke in the OnCreate of our Activity, the first one is setStatusBar() , that is in charge of making transparent to the same one.
private fun setStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
statusBarColor = Color.TRANSPARENT
}
}
The second one, setMargins() is in charge of setting the margins corresponding to the views that are restricted with the top, since otherwise, these views would be seen below the StatusBar.
private fun setMargins() {
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.your_parent_view)
) { _, insets ->
val view = findViewById<FrameLayout>(R.id.your_child_view)
val params = view.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(
0,
insets.systemWindowInsetTop,
0,
0
)
view.layoutParams = params
insets.consumeSystemWindowInsets()
}
}
The final code would look like:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.your_layout))
setStatusBar()
setMargins()
}
private fun setStatusBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
statusBarColor = Color.TRANSPARENT
}
}
private fun setMargins() {
ViewCompat.setOnApplyWindowInsetsListener(
findViewById(R.id.your_parent_view)
) { _, insets ->
val view = findViewById<FrameLayout>(R.id.your_child_view)
val params = view.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(
0,
insets.systemWindowInsetTop,
0,
0
)
view.layoutParams = params
insets.consumeSystemWindowInsets()
}
}
You can find a more detailed explanation of all this in the following Post
I also leave a Test Project where these concepts are working.
If you are using React Native, other posts don't work. React has its own way to deal with it.
<StatusBar translucent backgroundColor="transparent" />
from react-native
is the way to go, thx to this post this will override android setting in App.
However, 2 things to know:
<Header />
component from react-native-elements
, it already have <StatusBar />
included, using its statusBarProps
instead.Most elegant solution in 2022:
private fun hideStatusBar() {
val windowInsetsController = ViewCompat.getWindowInsetsController(window.decorView) ?: return
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars())
}
To achieve completely transparent status bar: First make the custom theme in themes.xml as
<style name="QuiloThemeLight" parent="Theme.AppCompat.Light.NoActionBar">
Java:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
getWindow().setStatusBarColor(Color.TRANSPARENT);
Kotlin:
activity.window.apply {
clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
statusBarColor = Color.TRANSPARENT
}
For the last update from google. This is my code. This will transparent for statusbar and navigationbar: Change your theme to this:
<style name="Theme.Pink"
parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/pink_primary</item>
<item name="colorPrimaryVariant">@color/pink_dark</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/pink_light</item>
<item name="colorSecondaryVariant">@color/pink_primary</item>
<item name="colorOnSecondary">@color/black</item>
<item name="android:textColor">?attr/colorOnPrimary</item>
<!-- Status bar color. -->
<!-- Customize your theme here. -->
//transparent statusbar
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowIsTranslucent">true</item>
//transparent navigationbar
<item name="android:windowTranslucentNavigation">true</item>
</style>
Then in layout (file xml): Add 2 properties point_top and point_bottom to determine the position of the margin value of other components of the app:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_activity">
<TextView
android:id="@+id/point_top"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/point_bottom"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<.....>
</androidx.constraintlayout.widget.ConstraintLayout>
Then in baseActivity or yourActivity: add this code in onCreate:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = setLayout()
//set inset for view
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets ->
val paramsTop =
findViewById<TextView>(R.id.point_top).layoutParams as MarginLayoutParams
paramsTop.setMargins(0, insets.getInsets(WindowInsetsCompat.Type.systemBars()).top, 0, 0)
findViewById<TextView>(R.id.point_top).layoutParams = paramsTop
val paramsBottom =
findViewById<TextView>(R.id.point_bottom).layoutParams as MarginLayoutParams
paramsBottom.setMargins(0, 0, 0, insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom)
findViewById<TextView>(R.id.point_bottom).layoutParams = paramsBottom
insets.consumeSystemWindowInsets()
}
setContentView(binding.root)
}
Hope this to help everyone.
This is only for API Level >= 21. It works for me. Here is my code (Kotlin)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<View>(android.R.id.content).systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
}
I found the answer while I investigating this library: https://github.com/laobie/StatusBarUtil
so you need to add following codes to your activity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.statusBarColor = Color.TRANSPARENT
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.