Refactor: Cleaned up the way that icons are displayed.

Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
This commit is contained in:
HeCodes2Much
2024-09-05 14:48:46 +01:00
parent aa83050c3f
commit afd52c3440
5 changed files with 192 additions and 202 deletions

View File

@@ -0,0 +1,88 @@
package com.github.droidworksstudio.common
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import androidx.core.graphics.ColorUtils
import androidx.core.graphics.drawable.DrawableCompat
import androidx.palette.graphics.Palette
import kotlin.math.min
class ColorIconsExtensions {
companion object {
fun drawableToBitmap(drawable: Drawable): Bitmap {
if (drawable is BitmapDrawable) {
return drawable.bitmap
}
val width = drawable.intrinsicWidth.coerceAtLeast(1)
val height = drawable.intrinsicHeight.coerceAtLeast(1)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
fun getDominantColor(bitmap: Bitmap): Int {
// Scale the bitmap to a manageable size
val scaledBitmap = Bitmap.createScaledBitmap(
bitmap,
min(bitmap.width / 4, 1280),
min(bitmap.height / 4, 1280),
true
)
// Generate a palette from the scaled bitmap
val palette = Palette.from(scaledBitmap)
.maximumColorCount(128)
.generate()
// Extract the colors from the palette
val colors = palette.swatches.map { it.rgb }
// Combine the colors into a single color
return increaseColorVibrancy(combineColors(colors))
}
private fun combineColors(colors: List<Int>): Int {
if (colors.isEmpty()) return Color.DKGRAY
var red = 0
var green = 0
var blue = 0
// Calculate the average color values
for (color in colors) {
red += Color.red(color)
green += Color.green(color)
blue += Color.blue(color)
}
val count = colors.size
return Color.rgb(red / count, green / count, blue / count)
}
private fun increaseColorVibrancy(color: Int): Int {
// Convert RGB to HSL
val hsl = FloatArray(3)
ColorUtils.colorToHSL(color, hsl)
// Increase the saturation
hsl[1] = (hsl[1] * 15f).coerceIn(0f, 1f)
// Convert HSL back to RGB
return ColorUtils.HSLToColor(hsl)
}
fun recolorDrawable(drawable: Drawable, color: Int): Drawable {
val wrappedDrawable = DrawableCompat.wrap(drawable)
DrawableCompat.setTint(wrappedDrawable, color)
return wrappedDrawable
}
}
}

View File

@@ -1,13 +1,14 @@
package com.github.droidworksstudio.launcher.ui.drawer
import android.util.Log
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.view.Gravity
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.github.droidworksstudio.common.ColorIconsExtensions
import com.github.droidworksstudio.common.dpToPx
import com.github.droidworksstudio.common.isWorkProfileEnabled
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.data.entities.AppInfo
import com.github.droidworksstudio.launcher.databinding.ItemDrawBinding
@@ -26,49 +27,62 @@ class DrawViewHolder(
fun bind(appInfo: AppInfo) {
binding.apply {
// Get the current LayoutParams of appHiddenName
val layoutParams = appDrawName.layoutParams as LinearLayoutCompat.LayoutParams
val layoutAppNameParams = appDrawName.layoutParams as LinearLayoutCompat.LayoutParams
// Set the margins
layoutParams.topMargin = preferenceHelper.homeAppPadding.toInt()
layoutParams.bottomMargin = preferenceHelper.homeAppPadding.toInt()
layoutAppNameParams.topMargin = preferenceHelper.homeAppPadding.toInt()
layoutAppNameParams.bottomMargin = preferenceHelper.homeAppPadding.toInt()
appDrawName.layoutParams = layoutParams
appDrawName.layoutParams = layoutAppNameParams
// Update appDrawName properties
appDrawName.text = appInfo.appName
appDrawName.setTextColor(preferenceHelper.appColor)
appDrawName.textSize = preferenceHelper.appTextSize
appDrawName.gravity = preferenceHelper.homeAppAlignment
Log.d("Tag", "Draw Adapter: ${appInfo.appName + appInfo.id} | ${appInfo.userHandle}")
val icon = AppCompatResources.getDrawable(appDrawName.context, R.drawable.work_profile)
val px = preferenceHelper.appTextSize.toInt().dpToPx()
icon?.setBounds(0, 0, px, px)
if (appInfo.userHandle > 0) {
val appLabelGravity = preferenceHelper.homeAppAlignment
if (appLabelGravity == Gravity.START) {
appDrawName.setCompoundDrawables(icon, null, null, null)
} else {
appDrawName.setCompoundDrawables(null, null, icon, null)
}
appDrawName.compoundDrawablePadding = 20
if (!appDrawName.context.isWorkProfileEnabled()) {
appDrawName.visibility = View.GONE
}
} else {
// If appInfo.work is false, remove the drawable
appDrawName.setCompoundDrawables(null, null, null, null)
appDrawName.compoundDrawablePadding = 0
}
if (preferenceHelper.showAppIcon) {
val appIcon =
binding.root.context.packageManager.getApplicationIcon(appInfo.packageName)
appDrawLeftIcon.setImageDrawable(appIcon)
appDrawLeftIcon.layoutParams.width =
preferenceHelper.appTextSize.toInt() * 3
appDrawLeftIcon.layoutParams.height =
preferenceHelper.appTextSize.toInt() * 3
appDrawLeftIcon.visibility = View.VISIBLE
val pm: PackageManager = binding.root.context.packageManager
val appIcon = pm.getApplicationIcon(appInfo.packageName)
val appIconSize = (preferenceHelper.appTextSize * if (preferenceHelper.showAppIconAsDots) 1.1f else 2f).toInt()
val layoutParams = LinearLayoutCompat.LayoutParams(appIconSize, appIconSize)
val appNewIcon: Drawable? = if (preferenceHelper.showAppIconAsDots) {
val newIcon = ContextCompat.getDrawable(itemView.context, R.drawable.app_dot_icon)!!
val bitmap = ColorIconsExtensions.drawableToBitmap(appIcon)
val dominantColor = ColorIconsExtensions.getDominantColor(bitmap)
ColorIconsExtensions.recolorDrawable(newIcon, dominantColor)
} else {
null
}
appDrawIcon.layoutParams = layoutParams
appDrawIcon.setImageDrawable(appNewIcon ?: appIcon)
appDrawIcon.visibility = View.VISIBLE
val parentLayout = appDrawName.parent as LinearLayoutCompat
parentLayout.orientation = LinearLayoutCompat.HORIZONTAL
parentLayout.removeAllViews()
when (preferenceHelper.homeAppAlignment) {
Gravity.START -> {
layoutParams.marginEnd = 10.dpToPx()
parentLayout.addView(appDrawIcon)
parentLayout.addView(appDrawName)
}
Gravity.END -> {
layoutParams.marginStart = 10.dpToPx()
parentLayout.addView(appDrawName)
parentLayout.addView(appDrawIcon)
}
else -> {
appDrawIcon.visibility = View.GONE
}
}
} else {
appDrawIcon.visibility = View.GONE
}
}

View File

@@ -2,26 +2,20 @@ package com.github.droidworksstudio.launcher.ui.home
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.view.Gravity
import android.view.View
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.graphics.drawable.DrawableCompat
import androidx.palette.graphics.Palette
import androidx.recyclerview.widget.RecyclerView
import com.github.droidworksstudio.common.ColorIconsExtensions
import com.github.droidworksstudio.common.dpToPx
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.data.entities.AppInfo
import com.github.droidworksstudio.launcher.databinding.ItemHomeBinding
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
import javax.inject.Inject
import kotlin.math.min
class HomeViewHolder @Inject constructor(
private val binding: ItemHomeBinding,
@@ -33,13 +27,14 @@ class HomeViewHolder @Inject constructor(
fun bind(appInfo: AppInfo) {
binding.apply {
// Get the current LayoutParams of appHiddenName
val layoutParams = appHomeName.layoutParams as LinearLayoutCompat.LayoutParams
val layoutAppNameParams = appHomeName.layoutParams as LinearLayoutCompat.LayoutParams
// Set the margins
layoutParams.topMargin = preferenceHelper.homeAppPadding.toInt()
layoutParams.bottomMargin = preferenceHelper.homeAppPadding.toInt()
layoutAppNameParams.topMargin = preferenceHelper.homeAppPadding.toInt()
layoutAppNameParams.bottomMargin = preferenceHelper.homeAppPadding.toInt()
appHomeName.layoutParams = layoutAppNameParams
appHomeName.layoutParams = layoutParams
// Update appHomeName properties
appHomeName.text = appInfo.appName
appHomeName.setTextColor(preferenceHelper.appColor)
@@ -49,60 +44,48 @@ class HomeViewHolder @Inject constructor(
if (preferenceHelper.showAppIcon) {
val pm: PackageManager = binding.root.context.packageManager
val appIcon = pm.getApplicationIcon(appInfo.packageName)
val appIconSize = (preferenceHelper.appTextSize * if (preferenceHelper.showAppIconAsDots) 1.1f else 2f).toInt()
if (preferenceHelper.showAppIconAsDots) {
when (preferenceHelper.homeAppAlignment) {
Gravity.START -> {
val appNewIcon
: Drawable = ContextCompat.getDrawable(itemView.context, R.drawable.app_dot_icon)!!
val bitmap = drawableToBitmap(appIcon)
val dominantColor = getDominantColor(bitmap)
val recoloredDrawable = recolorDrawable(appNewIcon, dominantColor)
val appIconSize = (preferenceHelper.appTextSize * 1.1f).toInt()
appHomeDotsIcon.setImageDrawable(recoloredDrawable)
appHomeDotsIcon.layoutParams.width = appIconSize
appHomeDotsIcon.layoutParams.height = appIconSize
appHomeDotsIcon.visibility = View.VISIBLE
}
else -> {
appHomeDotsIcon.visibility = View.GONE
}
}
val layoutParams = LinearLayoutCompat.LayoutParams(appIconSize, appIconSize)
val appNewIcon: Drawable? = if (preferenceHelper.showAppIconAsDots) {
val newIcon = ContextCompat.getDrawable(itemView.context, R.drawable.app_dot_icon)!!
val bitmap = ColorIconsExtensions.drawableToBitmap(appIcon)
val dominantColor = ColorIconsExtensions.getDominantColor(bitmap)
ColorIconsExtensions.recolorDrawable(newIcon, dominantColor)
} else {
val appIconSize = (preferenceHelper.appTextSize * 2f).toInt()
when (preferenceHelper.homeAppAlignment) {
Gravity.START -> {
appHomeLeftIcon.setImageDrawable(appIcon)
appHomeLeftIcon.layoutParams.width = appIconSize
appHomeLeftIcon.layoutParams.height = appIconSize
appHomeLeftIcon.visibility = View.VISIBLE
}
null
}
Gravity.END -> {
appHomeRightIcon.setImageDrawable(appIcon)
appHomeRightIcon.layoutParams.width = appIconSize
appHomeRightIcon.layoutParams.height = appIconSize
appHomeRightIcon.visibility = View.VISIBLE
}
appHomeIcon.layoutParams = layoutParams
appHomeIcon.setImageDrawable(appNewIcon ?: appIcon)
appHomeIcon.visibility = View.VISIBLE
else -> {
appHomeLeftIcon.visibility = View.GONE
appHomeRightIcon.visibility = View.GONE
}
val parentLayout = appHomeName.parent as LinearLayoutCompat
parentLayout.orientation = LinearLayoutCompat.HORIZONTAL
parentLayout.removeAllViews()
when (preferenceHelper.homeAppAlignment) {
Gravity.START -> {
layoutParams.marginEnd = 10.dpToPx()
parentLayout.addView(appHomeIcon)
parentLayout.addView(appHomeName)
}
Gravity.END -> {
layoutParams.marginStart = 10.dpToPx()
parentLayout.addView(appHomeName)
parentLayout.addView(appHomeIcon)
}
else -> {
appHomeIcon.visibility = View.GONE
}
}
} else {
// Hide icons if app icon is not shown
appHomeLeftIcon.visibility = View.GONE
appHomeRightIcon.visibility = View.GONE
appHomeDotsIcon.visibility = View.GONE
appHomeIcon.visibility = View.GONE
}
}
itemView.setOnClickListener {
onAppClickedListener.onAppClicked(appInfo)
}
@@ -112,77 +95,4 @@ class HomeViewHolder @Inject constructor(
true
}
}
private fun drawableToBitmap(drawable: Drawable): Bitmap {
if (drawable is BitmapDrawable) {
return drawable.bitmap
}
val width = drawable.intrinsicWidth.coerceAtLeast(1)
val height = drawable.intrinsicHeight.coerceAtLeast(1)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
return bitmap
}
private fun getDominantColor(bitmap: Bitmap): Int {
// Scale the bitmap to a manageable size
val scaledBitmap = Bitmap.createScaledBitmap(
bitmap,
min(bitmap.width / 4, 1280),
min(bitmap.height / 4, 1280),
true
)
// Generate a palette from the scaled bitmap
val palette = Palette.from(scaledBitmap)
.maximumColorCount(128)
.generate()
// Extract the colors from the palette
val colors = palette.swatches.map { it.rgb }
// Combine the colors into a single color
return increaseColorVibrancy(combineColors(colors))
}
private fun combineColors(colors: List<Int>): Int {
if (colors.isEmpty()) return Color.DKGRAY
var red = 0
var green = 0
var blue = 0
// Calculate the average color values
for (color in colors) {
red += Color.red(color)
green += Color.green(color)
blue += Color.blue(color)
}
val count = colors.size
return Color.rgb(red / count, green / count, blue / count)
}
private fun increaseColorVibrancy(color: Int): Int {
// Convert RGB to HSL
val hsl = FloatArray(3)
ColorUtils.colorToHSL(color, hsl)
// Increase the saturation
hsl[1] = (hsl[1] * 15f).coerceIn(0f, 1f)
// Convert HSL back to RGB
return ColorUtils.HSLToColor(hsl)
}
private fun recolorDrawable(drawable: Drawable, color: Int): Drawable {
val wrappedDrawable = DrawableCompat.wrap(drawable)
DrawableCompat.setTint(wrappedDrawable, color)
return wrappedDrawable
}
}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="wrap_content">
@@ -9,6 +8,7 @@
android:id="@+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
@@ -16,35 +16,28 @@
android:id="@+id/appDrawDots_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="10dp"
android:visibility="gone" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/appDrawLeft_icon"
android:id="@+id/appDraw_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginEnd="16dp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/linear_layout" />
android:layout_marginStart="10dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="10dp"
android:visibility="gone" />
<androidx.appcompat.widget.LinearLayoutCompat
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/appDraw_name"
style="@style/TextDefaultStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/appDraw_name"
style="@style/TextDefaultStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="24sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
android:gravity="center"
android:textSize="24sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -13,18 +13,10 @@
tools:ignore="MissingConstraints">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/appHomeDots_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:layout_marginEnd="10dp"
android:visibility="gone" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/appHomeLeft_icon"
android:id="@+id/appHome_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="10dp"
android:layout_marginTop="1dp"
android:visibility="gone" />
<androidx.appcompat.widget.AppCompatTextView
@@ -36,12 +28,5 @@
android:gravity="center"
android:textSize="24sp" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/appHomeRight_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="10dp"
android:visibility="gone" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>