Skip to content

fix(core): don't overwrite existing icons when no ico_ attribute is set - #669

Merged
mikepenz merged 2 commits into
developfrom
fix/menu-inflater-keeps-existing-icons
Aug 20, 2026
Merged

fix(core): don't overwrite existing icons when no ico_ attribute is set#669
mikepenz merged 2 commits into
developfrom
fix/menu-inflater-keeps-existing-icons

Conversation

@mikepenz

@mikepenz mikepenz commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Follow-up on top of #667, which fixed the reported symptom (#666). Same bug, addressed one layer down so it covers every call site.

Root cause

IconicsAttrsApplier.getIconicsDrawable() is declared nullable and all three call sites treat null as "no iconics data here, leave the target alone":

IconicsAttrsApplier.getIconicsDrawable(context, attrs)?.let { menuItem.icon = it }

But it never returns null. IconicsAttrsExtractor.extract() ends in createIfNeeds(), so an AttributeSet with no ico_* attribute still yields an empty IconicsDrawable — and that empty drawable then replaces whatever icon the target already had.

That is why a menu item declaring only android:icon came back blank. The same applies to the ActionMenuItemView and ImageView branches of IconicsFactory, so an android:src is clobbered too whenever IconicsLayoutInflater is in use — which #667's menu-inflater-local fix does not reach.

Changes

Return null when the obtained TypedArray holds none of the styleable's attributes:

if (it.indexCount == 0) return@use null

R.styleable.Iconics contains only ico_* attributes, so indexCount == 0 means exactly "this tag declares no iconics data". No behaviour change for anything that does declare one.

With that in place the name.startsWith("ico_") check from #667 is redundant, and is removed in the second commit — the author flagged it as brittle under attribute renames, and it covered the menu inflater only.

Tests

app/src/test/.../IconicsMenuInflaterUtilTest.kt, Robolectric, over the existing menu_playground resource, which already had the two interesting cases and now also has an item with no icon at all:

  • menu_item_1 — plain android:icon, no ico_* → drawable must be left untouched (asserted by identity)
  • menu_item_2ico_icon/ico_color/ico_size → must become an IconicsDrawable
  • menu_item_3 — no icon at all → must stay without one

Both regression tests fail with the fix reverted and pass with it. This is the first unit test in the repo, so it also brings in Robolectric and includeAndroidResources for the app module.

Copilot AI lite review requested due to automatic review settings August 20, 2026 16:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

mikepenz and others added 2 commits August 20, 2026 18:33
IconicsAttrsApplier.getIconicsDrawable() always returned a drawable, even
for an AttributeSet carrying no `ico_*` attribute at all, because the
extractor falls back to creating an empty IconicsDrawable. Every caller
treats a non-null result as "there is iconics data here" and assigns it,
so a menu item's `android:icon` or an ImageView's `android:src` got
replaced by an empty drawable.

Return null when the styled attributes are empty, which is what all three
call sites (IconicsMenuInflaterUtil, and the ActionMenuItemView / ImageView
branches of IconicsFactory) already handle.

Adds regression tests over `menu_playground`, which covers an item with a
plain `android:icon`, an item defined via `ico_*` attributes and an item
with no icon at all.

Fixes #666
Supersedes #667
Co-authored-by: PrOF-kk <valerio.colella.2001@gmail.com>
Superseded by the null return in IconicsAttrsApplier: matching attribute
names by their `ico_` prefix breaks if an attribute is ever renamed, and it
only covered the menu inflater while IconicsFactory had the same problem.
@mikepenz
mikepenz force-pushed the fix/menu-inflater-keeps-existing-icons branch from b1630e3 to ae354b7 Compare August 20, 2026 16:34
Comment thread app/build.gradle
implementation project(':weather-icons-typeface-library')

testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.16'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ A newer version of org.robolectric:robolectric than 4.16 is available: 4.16.1

<!-- neither an `android:icon` nor any `ico_*` attribute: must stay without an icon -->
<item
android:id="@+id/menu_item_3"
android:title="Item 3"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Hardcoded string "Item 3", should use @string resource

@mikepenz
mikepenz merged commit 5f3193c into develop Aug 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants