Skip to content

Commit

Permalink
fix(#131): set proper system UI colors for status and nav bars (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkuester authored Jul 13, 2023
1 parent 73ad9b2 commit 1801136
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 40 deletions.
27 changes: 6 additions & 21 deletions app/src/main/java/com/sduduzog/slimlauncher/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.navigation.Navigation.findNavController
import com.sduduzog.slimlauncher.utils.*
import dagger.hilt.android.AndroidEntryPoint
import java.lang.reflect.Method
import javax.inject.Inject
import kotlin.math.absoluteValue


Expand All @@ -27,6 +28,8 @@ class MainActivity : AppCompatActivity(),

private val wallpaperManager = WallpaperManager(this)

@Inject
lateinit var systemUiManager: SystemUiManager
private lateinit var settings: SharedPreferences
private lateinit var navigator: NavController
private lateinit var homeWatcher: HomeWatcher
Expand Down Expand Up @@ -68,7 +71,7 @@ class MainActivity : AppCompatActivity(),
override fun onResume() {
super.onResume()
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
toggleStatusBar()
systemUiManager.setSystemUiVisibility()
}

override fun onStart() {
Expand All @@ -88,15 +91,15 @@ class MainActivity : AppCompatActivity(),

override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) toggleStatusBar()
if (hasFocus) systemUiManager.setSystemUiVisibility()
}

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, s: String?) {
if (s.equals(getString(R.string.prefs_settings_key_theme), true)) {
recreate()
}
if (s.equals(getString(R.string.prefs_settings_key_toggle_status_bar), true)) {
toggleStatusBar()
systemUiManager.setSystemUiVisibility()
}
}

Expand Down Expand Up @@ -125,24 +128,6 @@ class MainActivity : AppCompatActivity(),
navigator.popBackStack(R.id.homeFragment, false)
}

private fun showSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
}

private fun hideSystemUI() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}

private fun toggleStatusBar() {
val isHidden = settings.getBoolean(getString(R.string.prefs_settings_key_toggle_status_bar), false)
if (isHidden) {
hideSystemUI()
} else {
showSystemUI()
}
}

companion object {
@StyleRes
fun resolveTheme(i: Int): Int {
Expand Down
24 changes: 5 additions & 19 deletions app/src/main/java/com/sduduzog/slimlauncher/utils/BaseFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,26 @@ package com.sduduzog.slimlauncher.utils
import android.content.Context
import android.content.Intent
import android.content.pm.LauncherApps
import android.os.Build
import android.os.Process
import android.os.UserManager
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityOptionsCompat
import androidx.fragment.app.Fragment
import com.sduduzog.slimlauncher.BuildConfig
import com.sduduzog.slimlauncher.R
import com.sduduzog.slimlauncher.data.model.App
import javax.inject.Inject

abstract class BaseFragment : Fragment(), ISubscriber {
@Inject
lateinit var systemUiManager: SystemUiManager

abstract fun getFragmentView(): ViewGroup


override fun onResume() {
super.onResume()
val settings = requireContext().getSharedPreferences(getString(R.string.prefs_settings), AppCompatActivity.MODE_PRIVATE)
val active = settings.getInt(getString(R.string.prefs_settings_key_theme), 0)


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
when (active) {
0, 3, 5 -> {
val flags = requireActivity().window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
getFragmentView().systemUiVisibility = flags
}
}
val value = TypedValue()
requireContext().theme.resolveAttribute(R.attr.colorPrimary, value, true)
requireActivity().window.statusBarColor = value.data
}
systemUiManager.setSystemUiColors()
}

override fun onStart() {
Expand Down
151 changes: 151 additions & 0 deletions app/src/main/java/com/sduduzog/slimlauncher/utils/SystemUiManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package com.sduduzog.slimlauncher.utils

import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.Build
import android.util.TypedValue
import android.view.View
import android.view.Window
import android.view.WindowInsets
import android.view.WindowInsetsController
import android.view.WindowManager
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.sduduzog.slimlauncher.R
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.qualifiers.ActivityContext

@Module
@InstallIn(ActivityComponent::class)
open class SystemUiManager internal constructor(internal val context: Context) {
internal val window: Window = (context as Activity).window
internal val settings: SharedPreferences = context.getSharedPreferences(
context.getString(R.string.prefs_settings),
AppCompatActivity.MODE_PRIVATE
)

companion object {
@Provides
fun createInstance(@ActivityContext context: Context): SystemUiManager {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
(context as Activity).window.attributes.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return LSystemUiManager(context)
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
return MSystemUiManager(context)
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
return OSystemUiManager(context)
}
return SystemUiManager(context)
}
}

@TargetApi(Build.VERSION_CODES.R)
open fun setSystemUiVisibility() {
val insetsController = window.insetsController

if (isSystemUiHidden()) {
insetsController?.hide(WindowInsets.Type.statusBars())
} else {
insetsController?.show(WindowInsets.Type.statusBars())
}

if (isLightModeTheme()) {
insetsController?.setSystemBarsAppearance(
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
)
insetsController?.setSystemBarsAppearance(
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS,
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
)
} else {
insetsController?.setSystemBarsAppearance(
0,
WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
)
insetsController?.setSystemBarsAppearance(
0,
WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
)
}
}

@TargetApi(Build.VERSION_CODES.O)
open fun setSystemUiColors() {
val primaryColor = getPrimaryColor()
window.statusBarColor = primaryColor
window.navigationBarColor = primaryColor
}

internal fun getPrimaryColor(): Int {
val primaryColor = TypedValue()
context.theme.resolveAttribute(R.attr.colorPrimary, primaryColor, true)
return primaryColor.data
}

internal fun isSystemUiHidden(): Boolean {
return settings.getBoolean(
context.getString(R.string.prefs_settings_key_toggle_status_bar),
false
)
}

internal fun isLightModeTheme(): Boolean {
val theme = settings.getInt(context.getString(R.string.prefs_settings_key_theme), 0)
val uiMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return listOf(
6,
3,
5
).contains(theme) || (theme == 0 && uiMode == Configuration.UI_MODE_NIGHT_NO)
}

private open class OSystemUiManager(context: Context) : SystemUiManager(context) {
@RequiresApi(Build.VERSION_CODES.O)
override fun setSystemUiVisibility() {
window.decorView.systemUiVisibility =
getLightUiBarFlags() or getToggleStatusBarFlags()
}

@RequiresApi(Build.VERSION_CODES.O)
open fun getLightUiBarFlags(): Int {
return if (isLightModeTheme()) View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR else 0
}

private fun getToggleStatusBarFlags(): Int {
return View.SYSTEM_UI_FLAG_LAYOUT_STABLE or if (isSystemUiHidden()) View.SYSTEM_UI_FLAG_FULLSCREEN else 0
}
}

private open class MSystemUiManager(context: Context) : OSystemUiManager(context) {
@RequiresApi(Build.VERSION_CODES.M)
override fun setSystemUiColors() {
window.statusBarColor = getPrimaryColor()
}

@RequiresApi(Build.VERSION_CODES.M)
override fun getLightUiBarFlags(): Int {
return if (isLightModeTheme()) View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR else 0
}
}

private class LSystemUiManager(context: Context) : MSystemUiManager(context) {
override fun setSystemUiColors() {}

override fun getLightUiBarFlags(): Int {
return 0
}
}
}

0 comments on commit 1801136

Please sign in to comment.