August 21, 2017

Tinted status bar in Android

by horse315
by horse315
Tinted status bar in Android

From https://github.com/mapsme/omim/blob/master/android/src/com/mapswithme/util/UiUtils.java

Your UIUtils or base activity class:

fun setupStatusBar(activity: Activity){
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        activity.window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
    } else {
        activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    }

    val statusBarTintView = View(activity).also {
        it.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)).also { it.gravity = Gravity.TOP }
        it.setBackgroundColor(ResourcesCompat.getColor(activity.resources, R.color.statusBarTint, activity.theme))
        it.visibility = View.VISIBLE
    }

    activity.window.decorView.let {it as ViewGroup}.addView(statusBarTintView)
}

fun getStatusBarHeight(context: Context): Int {
    var result = 0
    val res = context.resources
    val resourceId = res.getIdentifier("status_bar_height", "dimen", "android")
    if (resourceId > 0)
        result = res.getDimensionPixelSize(resourceId)

    return result
}

Your activity theme should have transparent status bar:

<style name="...">
    <item name="android:statusBarColor" tools:targetApi="lollipop">@android:color/transparent</item>
</style>

Your layout should not fit system windows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false" 
    tools:context="com.nakedhearts.elbi.MainActivity">
</android.support.constraint.ConstraintLayout>

Your activity should apply styling in code:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    UIUtils.setupStatusBar(this)

    setContentView(R.layout.activity_main)
}
DevelopmentAndroid