Ver Fonte

fix(#131): set proper system UI colors for status and nav bars (#145)

Joshua Kuestersteffen há 2 anos atrás
pai
commit
18011365dd

+ 6 - 21
app/src/main/java/com/sduduzog/slimlauncher/MainActivity.kt

@@ -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
 
 
@@ -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
@@ -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() {
@@ -88,7 +91,7 @@ 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?) {
@@ -96,7 +99,7 @@ class MainActivity : AppCompatActivity(),
             recreate()
         }
         if (s.equals(getString(R.string.prefs_settings_key_toggle_status_bar), true)) {
-            toggleStatusBar()
+            systemUiManager.setSystemUiVisibility()
         }
     }
 
@@ -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 {

+ 5 - 19
app/src/main/java/com/sduduzog/slimlauncher/utils/BaseFragment.kt

@@ -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() {

+ 151 - 0
app/src/main/java/com/sduduzog/slimlauncher/utils/SystemUiManager.kt

@@ -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
+        }
+    }
+}