Improve splash screen adaptive icon support
This commit is contained in:
parent
88bbfc41f4
commit
51aa25834e
@ -3,6 +3,8 @@ package de.mm20.launcher2.ui.component
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.graphics.drawable.AdaptiveIconDrawable
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.TypedValue
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
@ -33,6 +35,9 @@ import de.mm20.launcher2.search.SavableSearchable
|
||||
import de.mm20.launcher2.search.data.LauncherApp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@Composable
|
||||
fun FakeSplashScreen(
|
||||
@ -92,7 +97,12 @@ fun rememberSplashScreenData(searchable: SavableSearchable?): SplashScreenData {
|
||||
val context = LocalContext.current
|
||||
val defaultBackgroundColor = MaterialTheme.colorScheme.background
|
||||
val state = remember {
|
||||
mutableStateOf(SplashScreenData(backgroundColor = defaultBackgroundColor, iconSize = 288.dp))
|
||||
mutableStateOf(
|
||||
SplashScreenData(
|
||||
backgroundColor = defaultBackgroundColor,
|
||||
iconSize = 288.dp
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
LaunchedEffect(searchable) {
|
||||
@ -184,7 +194,7 @@ fun rememberSplashScreenData(searchable: SavableSearchable?): SplashScreenData {
|
||||
|
||||
var iconSize = 288.dp
|
||||
|
||||
var iconBackground = if (typedValue.isColor && typedValue.data != 0) {
|
||||
val iconBackground = if (typedValue.isColor && typedValue.data != 0) {
|
||||
iconSize = 240.dp
|
||||
Color(typedValue.data)
|
||||
} else {
|
||||
@ -193,7 +203,19 @@ fun rememberSplashScreenData(searchable: SavableSearchable?): SplashScreenData {
|
||||
|
||||
if (icon == null) {
|
||||
icon = activityInfo.loadIcon(context.packageManager)
|
||||
iconSize = 160.dp
|
||||
iconSize = 240.dp
|
||||
}
|
||||
|
||||
if (icon is AdaptiveIconDrawable) {
|
||||
val bg = icon.background
|
||||
if (bg is ColorDrawable && backgroundColor != null && iconBackground == null &&
|
||||
isRgbSimilarInHsv(bg.color, backgroundColor)
|
||||
) {
|
||||
icon = icon.foreground
|
||||
iconSize = 288.dp
|
||||
} else {
|
||||
iconSize = 160.dp
|
||||
}
|
||||
}
|
||||
|
||||
state.value = SplashScreenData(
|
||||
@ -211,4 +233,51 @@ fun rememberSplashScreenData(searchable: SavableSearchable?): SplashScreenData {
|
||||
}
|
||||
|
||||
internal val TypedValue.isColor
|
||||
get() = type in TypedValue.TYPE_FIRST_COLOR_INT..TypedValue.TYPE_LAST_COLOR_INT
|
||||
get() = type in TypedValue.TYPE_FIRST_COLOR_INT..TypedValue.TYPE_LAST_COLOR_INT
|
||||
|
||||
|
||||
/*
|
||||
* From: https://android.googlesource.com/platform/frameworks/base/+/f05f9b960832b6272b6740721c0a4bbd1ce632c1/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java#550
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
internal fun isRgbSimilarInHsv(a: Int, b: Int): Boolean {
|
||||
if (a == b) {
|
||||
return true
|
||||
}
|
||||
val lumA: Float = android.graphics.Color.luminance(a)
|
||||
val lumB: Float = android.graphics.Color.luminance(b)
|
||||
val contrastRatio =
|
||||
if (lumA > lumB) (lumA + 0.05f) / (lumB + 0.05f) else (lumB + 0.05f) / (lumA + 0.05f)
|
||||
if (contrastRatio < 2) {
|
||||
return true
|
||||
}
|
||||
val aHsv = FloatArray(3)
|
||||
val bHsv = FloatArray(3)
|
||||
android.graphics.Color.colorToHSV(a, aHsv)
|
||||
android.graphics.Color.colorToHSV(b, bHsv)
|
||||
// Minimum degree of the hue between two colors, the result range is 0-180.
|
||||
var minAngle = abs(aHsv[0] - bHsv[0]).toInt()
|
||||
minAngle = (minAngle + 180) % 360 - 180
|
||||
|
||||
// Calculate the difference between two colors based on the HSV dimensions.
|
||||
val normalizeH = minAngle / 180f
|
||||
val squareH = normalizeH.toDouble().pow(2.0)
|
||||
val squareS = (aHsv[1] - bHsv[1]).toDouble().pow(2.0)
|
||||
val squareV = (aHsv[2] - bHsv[2]).toDouble().pow(2.0)
|
||||
val square = squareH + squareS + squareV
|
||||
val mean = square / 3
|
||||
val root = sqrt(mean)
|
||||
return root < 0.1
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user