Skip to content

Commit a2c66fc

Browse files
feat(widget): Enhance home apps widget with icons and improve update mechanism
This commit introduces several improvements to the home apps widget: - **Icon Display:** The widget now displays app icons alongside app names. - A new function `createWidgetTextWithIcon` in `HomeAppsWidgetProvider.kt` handles rendering the app icon and label as a single Bitmap. - `item_home_app.xml` has been updated to use an `ImageView` (`appIcon`) instead of a `TextView` to display this combined image. - Icon loading logic now considers icon packs and provides a fallback to system icons. - Icon tinting is applied based on the dominant color of the icon. - **Widget Update Trigger:** - A new utility function `updateHomeWidget` in `SystemUtils.kt` has been created to send an update broadcast to the `HomeAppsWidgetProvider`. - This function is now called from `SettingsFragment.kt` whenever relevant settings that affect the home widget's appearance are changed (e.g., home app selection, app color, icon pack). This ensures the widget reflects changes immediately. - **Layout Adjustments:** - Padding has been reduced in `widget_word_of_the_day.xml`, `widget_fab.xml`, and `widget_home_apps.xml` for a more compact appearance. - Padding in `item_home_app.xml` is now applied to the `ImageView` to control spacing around the icon and text. These changes provide a more visually appealing and responsive home screen widget. Signed-off-by: CreativeCodeCat <wayne6324@gmail.com>
1 parent ee5017f commit a2c66fc

File tree

7 files changed

+127
-30
lines changed

7 files changed

+127
-30
lines changed

app/src/main/java/com/github/droidworksstudio/mlauncher/helper/SystemUtils.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import android.app.AlarmManager
55
import android.app.AppOpsManager
66
import android.app.UiModeManager
77
import android.app.role.RoleManager
8+
import android.appwidget.AppWidgetManager
9+
import android.content.ComponentName
810
import android.content.Context
911
import android.content.DialogInterface
1012
import android.content.Intent
@@ -54,6 +56,7 @@ import com.github.droidworksstudio.mlauncher.data.Message
5456
import com.github.droidworksstudio.mlauncher.data.Prefs
5557
import com.github.droidworksstudio.mlauncher.helper.utils.packageNames
5658
import com.github.droidworksstudio.mlauncher.services.ActionService
59+
import com.github.droidworksstudio.mlauncher.ui.widgets.home.HomeAppsWidgetProvider
5760
import com.google.android.material.dialog.MaterialAlertDialogBuilder
5861
import org.xmlpull.v1.XmlPullParser
5962
import java.io.File
@@ -633,6 +636,18 @@ fun getSystemIcons(
633636
}
634637
}
635638

639+
fun updateHomeWidget(context: Context) {
640+
// --- Trigger widget update ---
641+
val intent = Intent(context, HomeAppsWidgetProvider::class.java).apply {
642+
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
643+
// Optional: pass widget IDs if you want to update specific widgets
644+
val ids = AppWidgetManager.getInstance(context)
645+
.getAppWidgetIds(ComponentName(context, HomeAppsWidgetProvider::class.java))
646+
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)
647+
}
648+
context.sendBroadcast(intent)
649+
}
650+
636651
private fun getAppListIcons(context: Context, prefs: Prefs, nonNullDrawable: Drawable): Drawable? {
637652
return when (prefs.iconPackAppList) {
638653
Constants.IconPacks.CloudDots -> {

app/src/main/java/com/github/droidworksstudio/mlauncher/ui/SettingsFragment.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import com.github.droidworksstudio.mlauncher.helper.setThemeMode
8787
import com.github.droidworksstudio.mlauncher.helper.setTopPadding
8888
import com.github.droidworksstudio.mlauncher.helper.showNavigationBar
8989
import com.github.droidworksstudio.mlauncher.helper.showStatusBar
90+
import com.github.droidworksstudio.mlauncher.helper.updateHomeWidget
9091
import com.github.droidworksstudio.mlauncher.helper.utils.AppReloader
9192
import com.github.droidworksstudio.mlauncher.helper.utils.PrivateSpaceManager
9293
import com.github.droidworksstudio.mlauncher.style.SettingsTheme
@@ -831,6 +832,9 @@ class SettingsFragment : Fragment() {
831832
// Do something with i
832833
prefs.setHomeAppModel(n, clearApp)
833834
}
835+
836+
// --- Trigger widget update ---
837+
updateHomeWidget(context)
834838
}
835839
)
836840
}
@@ -1416,6 +1420,9 @@ class SettingsFragment : Fragment() {
14161420
onItemSelected = { selectedColor ->
14171421
selectedAppColor = selectedColor
14181422
prefs.appColor = selectedColor
1423+
1424+
// --- Trigger widget update ---
1425+
updateHomeWidget(context)
14191426
})
14201427
}
14211428
)
@@ -1576,6 +1583,9 @@ class SettingsFragment : Fragment() {
15761583
prefs.iconPackHome =
15771584
newAppIcons // Persist selection in preferences
15781585
viewModel.iconPackHome.value = newAppIcons
1586+
1587+
// --- Trigger widget update ---
1588+
updateHomeWidget(context)
15791589
}
15801590
}
15811591
}

app/src/main/java/com/github/droidworksstudio/mlauncher/ui/widgets/home/HomeAppsWidgetProvider.kt

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,20 @@ import android.appwidget.AppWidgetManager
55
import android.appwidget.AppWidgetProvider
66
import android.content.Context
77
import android.content.Intent
8+
import android.graphics.Bitmap
9+
import android.graphics.Canvas
10+
import android.graphics.Paint
11+
import android.graphics.drawable.Drawable
812
import android.util.TypedValue
913
import android.widget.RemoteViews
14+
import androidx.core.graphics.createBitmap
15+
import com.github.droidworksstudio.common.ColorIconsExtensions
1016
import com.github.droidworksstudio.mlauncher.R
17+
import com.github.droidworksstudio.mlauncher.data.Constants
1118
import com.github.droidworksstudio.mlauncher.data.Prefs
19+
import com.github.droidworksstudio.mlauncher.helper.IconCacheTarget
20+
import com.github.droidworksstudio.mlauncher.helper.IconPackHelper.getSafeAppIcon
21+
import com.github.droidworksstudio.mlauncher.helper.getSystemIcons
1222

1323
class HomeAppsWidgetProvider : AppWidgetProvider() {
1424

@@ -22,55 +32,121 @@ class HomeAppsWidgetProvider : AppWidgetProvider() {
2232

2333
for (appWidgetId in appWidgetIds) {
2434
val rv = RemoteViews(context.packageName, R.layout.widget_home_apps)
25-
26-
// Clear previous views
2735
rv.removeAllViews(R.id.homeAppsLayout)
2836

29-
// Loop through apps dynamically
3037
for (i in 0 until numApps) {
3138
val appModel = prefs.getHomeAppModel(i)
32-
val packageName = appModel.activityPackage
39+
val packageName = appModel.label
3340
if (packageName.isEmpty()) continue
3441

3542
val itemRv = RemoteViews(context.packageName, R.layout.item_home_app)
3643

37-
// Get app label safely
44+
// --- App label ---
3845
val appLabel = try {
3946
context.packageManager.getApplicationLabel(
4047
context.packageManager.getApplicationInfo(packageName, 0)
4148
).toString()
4249
} catch (_: Exception) {
4350
packageName
4451
}
45-
itemRv.setTextViewText(R.id.appName, appLabel)
4652

47-
// Optional: text size/color from prefs
48-
itemRv.setTextViewTextSize(R.id.appName, TypedValue.COMPLEX_UNIT_SP, prefs.appSize.toFloat())
49-
itemRv.setTextColor(R.id.appName, prefs.appColor)
53+
// --- Get icon safely ---
54+
val iconPackPackage = prefs.customIconPackHome
55+
val drawable = getSafeAppIcon(
56+
context = context,
57+
packageName = appModel.activityPackage,
58+
useIconPack = (iconPackPackage.isNotEmpty() && prefs.iconPackHome == Constants.IconPacks.Custom),
59+
iconPackTarget = IconCacheTarget.HOME
60+
)
61+
62+
// Optional recolor
63+
val recoloredDrawable = getSystemIcons(context, prefs, IconCacheTarget.HOME, drawable) ?: drawable
64+
65+
// --- Create bitmap with text + icon ---
66+
val bitmap = createWidgetTextWithIcon(
67+
context = context,
68+
text = appLabel,
69+
drawable = recoloredDrawable,
70+
textSizeSp = prefs.appSize.toFloat(),
71+
textColor = prefs.appColor,
72+
iconOnLeft = prefs.homeAlignment == Constants.Gravity.Left,
73+
paddingPx = (prefs.textPaddingSize * 1.5f).toInt() // padding between icon and text
74+
)
75+
76+
// Get dominant color from bitmap
77+
val dominantColor = ColorIconsExtensions.getDominantColor(bitmap)
78+
79+
// Recolor the drawable
80+
ColorIconsExtensions.recolorDrawable(recoloredDrawable, dominantColor)
81+
82+
// Set bitmap into ImageView (replaces TextView)
83+
itemRv.setImageViewBitmap(R.id.appIcon, bitmap)
5084

51-
val bottomPadding = prefs.textPaddingSize // pixels, or convert dp to px
52-
itemRv.setViewPadding(R.id.appName, 0, 0, 0, bottomPadding)
85+
val textPaddingSize = prefs.textPaddingSize // pixels, or convert dp to px
86+
itemRv.setViewPadding(R.id.appIcon, 0, textPaddingSize, 0, textPaddingSize)
5387

54-
// Click intent
88+
// --- Click intent ---
5589
val clickIntent = Intent(context, HomeAppUpdateReceiver::class.java).apply {
5690
action = "HOME_APP_CLICK"
5791
putExtra("PACKAGE_NAME", packageName)
5892
}
5993
val pendingIntent = PendingIntent.getBroadcast(
60-
context,
61-
i,
62-
clickIntent,
63-
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
94+
context, i, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
6495
)
65-
itemRv.setOnClickPendingIntent(R.id.appName, pendingIntent)
96+
itemRv.setOnClickPendingIntent(R.id.appIcon, pendingIntent)
6697

67-
// Add item to the container
98+
// Add item to container
6899
rv.addView(R.id.homeAppsLayout, itemRv)
69100
}
70101

71102
appWidgetManager.updateAppWidget(appWidgetId, rv)
72103
}
73104
}
74105

106+
fun createWidgetTextWithIcon(
107+
context: Context,
108+
text: String,
109+
drawable: Drawable,
110+
textSizeSp: Float,
111+
textColor: Int,
112+
iconOnLeft: Boolean,
113+
paddingPx: Int
114+
): Bitmap {
115+
val prefs = Prefs(context)
116+
// Determine icon size relative to text
117+
var iconSize = (textSizeSp * 1.4f).toInt()
118+
if (prefs.iconPackHome == Constants.IconPacks.System || prefs.iconPackHome == Constants.IconPacks.Custom) iconSize = iconSize * 2
119+
120+
// Measure text
121+
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
122+
color = textColor
123+
textSize = TypedValue.applyDimension(
124+
TypedValue.COMPLEX_UNIT_SP, textSizeSp, context.resources.displayMetrics
125+
)
126+
}
127+
val textWidth = paint.measureText(text)
128+
val textHeight = paint.descent() - paint.ascent()
129+
val bitmapWidth = iconSize + paddingPx + textWidth.toInt()
130+
val bitmapHeight = iconSize.coerceAtLeast(textHeight.toInt())
131+
132+
val bitmap = createBitmap(bitmapWidth, bitmapHeight)
133+
val canvas = Canvas(bitmap)
134+
135+
val iconTop = (bitmapHeight - iconSize) / 2
136+
val textY = (bitmapHeight / 2f) - (paint.descent() + paint.ascent()) / 2
137+
138+
if (iconOnLeft) {
139+
drawable.setBounds(0, iconTop, iconSize, iconTop + iconSize)
140+
drawable.draw(canvas)
141+
canvas.drawText(text, iconSize + paddingPx.toFloat(), textY, paint)
142+
} else {
143+
canvas.drawText(text, 0f, textY, paint)
144+
drawable.setBounds((textWidth + paddingPx).toInt(), iconTop, bitmapWidth, iconTop + iconSize)
145+
drawable.draw(canvas)
146+
}
147+
148+
return bitmap
149+
}
150+
75151
}
76152

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
android:layout_width="match_parent"
4-
android:layout_height="wrap_content"
5-
android:padding="4dp">
4+
android:layout_height="wrap_content">
65

7-
<TextView
8-
android:id="@+id/appName"
9-
android:layout_width="match_parent"
6+
<ImageView
7+
android:id="@+id/appIcon"
8+
android:layout_width="wrap_content"
109
android:layout_height="wrap_content"
11-
android:gravity="center_vertical|start"
12-
android:padding="8dp"
13-
android:textColor="#000"
14-
android:textSize="16sp" />
10+
android:contentDescription="@string/app_name" />
1511
</FrameLayout>

app/src/main/res/layout/widget_fab.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
android:layout_height="wrap_content"
55
android:gravity="center"
66
android:orientation="horizontal"
7-
android:padding="8dp">
7+
android:padding="4dp">
88

99
<ImageView
1010
android:id="@+id/fabPhone"

app/src/main/res/layout/widget_home_apps.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
android:layout_height="wrap_content"
66
android:background="@android:color/transparent"
77
android:orientation="vertical"
8-
android:padding="16dp" />
8+
android:padding="4dp" />

app/src/main/res/layout/widget_word_of_the_day.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
android:layout_height="match_parent"
55
android:gravity="center"
66
android:orientation="vertical"
7-
android:padding="8dp">
7+
android:padding="4dp">
88

99
<TextView
1010
android:id="@+id/textViewWord"

0 commit comments

Comments
 (0)