Skip to content

Fix Material Slider ACW implementor build failure (#1484) - #1486

Merged
jonathanpeppers merged 2 commits into
mainfrom
fix/slider-1484-acw-implementor
Jun 29, 2026
Merged

Fix Material Slider ACW implementor build failure (#1484)#1486
jonathanpeppers merged 2 commits into
mainfrom
fix/slider-1484-acw-implementor

Conversation

@sheiksyedm

@sheiksyedm sheiksyedm commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the Java/ACW compile failure consumers hit when referencing the Xamarin.Google.Android.Material package in a .NET MAUI Android app — even without using the Slider control.

Fixes #1484.

SliderChangeListener is not abstract and does not override abstract method onValueChange(Object,float,boolean) in BaseOnChangeListener
RangeSliderChangeListener is not abstract and does not override abstract method onValueChange(Object,float,boolean) in BaseOnChangeListener
BaseOnSliderTouchListenerImplementor is not abstract and does not override abstract method onStopTrackingTouch(Object) in BaseOnSliderTouchListener
BaseOnChangeListenerImplementor is not abstract and does not override abstract method onValueChange(Object,float,boolean) in BaseOnChangeListener

Root cause

BaseOnChangeListener / BaseOnSliderTouchListener are @RestrictTo(LIBRARY_GROUP) (internal) base interfaces with type-erased generic methods (onValueChange(Object, float, boolean)). The public, recommended types are Slider.OnChangeListener / RangeSlider.OnChangeListener, which extend the base with strongly-typed methods.

Because the bound add/removeListener pair references the base interface, the generator emits internal Implementor types decorated with [Register]. Every consuming app generates Android Callable Wrappers for those [Register] types. After PR #1481 stripped the erased base methods (to fix an erasure clash), the implementors and event listeners no longer satisfied the still-present Java abstract methods, so javac failed in every consuming project.

Fix

  • Remove the restricted base interfaces BaseOnChangeListener / BaseOnSliderTouchListener from the binding — this stops the broken Implementor generation at the source.
  • Break the C# implements chain on the four typed sub-interfaces so they stand alone (no longer extending the removed base) — removes the type-erasure clash entirely.
  • Remove the auto-generated addOnChangeListener / removeOnChangeListener / addOnSliderTouchListener / removeOnSliderTouchListener methods and re-add typed overloads via Additions with the correct JNI signatures.

The public API now exposes the Android-recommended listeners:

slider.AddOnChangeListener(myListener);   // Slider.IOnChangeListener
slider.AddOnSliderTouchListener(touch);   // Slider.IOnSliderTouchListener

Bump nugetVersion to 1.14.0.4.

Why removal is safe

BaseOnChangeListener is @RestrictTo(LIBRARY_GROUP) — internal to the Material library, not part of Android's public surface. Dropping it aligns with Google's intent and steers users to Slider.IOnChangeListener / RangeSlider.IOnChangeListener.

Validation

  • Xamarin.Google.Android.Material.dll builds with 0 errors.
  • No *Implementor ACW types generated for the listeners.
  • Typed sub-interfaces preserved; PublicAPI updated accordingly.

Files changed

  • source/com.google.android.material/material/Transforms/Metadata.xml
  • source/com.google.android.material/material/Additions/SliderListenerMethods.cs (new)
  • source/com.google.android.material/material/PublicAPI/PublicAPI.Unshipped.txt
  • config.json (nugetVersion 1.14.0.3 → 1.14.0.4)

Remove the restricted BaseOnChangeListener/BaseOnSliderTouchListener base
interfaces and break the C# implements chain on the typed sub-interfaces to
avoid the ACW type-erasure clash. Re-add typed AddOn*/RemoveOn* listener
methods via Additions so the public API uses Slider.IOnChangeListener and
RangeSlider.IOnChangeListener as recommended by Android. Bump nugetVersion to
1.14.0.4.
Copilot AI review requested due to automatic review settings June 29, 2026 10:17

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.

Pull request overview

This PR updates the Material (Xamarin.Google.Android.Material) binding to prevent consumer-side javac failures caused by generated ACW implementors for the Material Slider’s restricted base listener interfaces. It does this by removing the restricted base interfaces from the bound surface, detaching the typed sub-interfaces from the removed base interfaces, and reintroducing listener add/remove APIs via typed Additions methods. It also bumps the NuGet revision to ship the binding-only fix.

Changes:

  • Remove BaseOnChangeListener / BaseOnSliderTouchListener from the binding and detach Slider.* / RangeSlider.* typed listener interfaces from those bases.
  • Remove the auto-generated BaseSlider add/remove listener methods and re-add typed AddOn*/RemoveOn* methods via Additions.
  • Bump nugetVersion for com.google.android.material:material from 1.14.0.3 to 1.14.0.4 and update PublicAPI accordingly.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
source/com.google.android.material/material/Transforms/Metadata.xml Removes restricted base listener interfaces and strips/rewires slider listener-related API surface to avoid broken implementor generation.
source/com.google.android.material/material/Additions/SliderListenerMethods.cs Adds typed AddOn*/RemoveOn* listener methods that invoke the correct JNI signatures without relying on the removed base interfaces.
source/com.google.android.material/material/PublicAPI/PublicAPI.Unshipped.txt Updates public API tracking to reflect removed base interfaces and the newly exposed typed listener methods/types.
config.json Bumps nugetVersion for the Material package to ship the binding fix.

Wrap the JNI invoke in try/finally so GC.KeepAlive runs even when the call
throws, preventing premature collection of the listener handle. Addresses PR
review feedback.
@jonathanpeppers
jonathanpeppers merged commit 47ce547 into main Jun 29, 2026
2 checks passed
@jonathanpeppers
jonathanpeppers deleted the fix/slider-1484-acw-implementor branch June 29, 2026 16:20
jonathanpeppers pushed a commit that referenced this pull request Jul 2, 2026
…and RangeSlider (#1493)

PR #1486 removed the auto-generated addOnChangeListener/addOnSliderTouchListener
methods from BaseSlider via remove-node and re-added them as hand-written Additions.
However, the binding generator only produces C# events for methods it sees in the
API XML — since the methods were removed from the generated API, the Change,
StartTrackingTouch, and StopTrackingTouch events were no longer emitted.

This caused a regression in 1.14.0.4 where Slider.Change (and touch events) were
missing, breaking existing .NET consumers who used the C# event syntax.

Fix: add the three events manually to SliderListenerMethods.cs for both Slider and
RangeSlider, using EventHelper.AddEventHandler/RemoveEventHandler with the already-
generated implementor types (IOnChangeListenerImplementor, IOnSliderTouchListenerImplementor).
This is exactly what the generator would have produced had the methods remained in
the generated API.

The ChangeEventArgs.P0 type changes from Java.Lang.Object (old erased-generic base)
to the concrete Slider/RangeSlider — a source-level improvement alongside the fix.

Bump nugetVersion 1.14.0.4 -> 1.14.0.5.

Fixes #1484
jonathanpeppers pushed a commit that referenced this pull request Jul 16, 2026
…lease builds (#1502)

Instead of removing the base interfaces entirely (PR #1486), keep them intact
with their methods so the binding generator produces Implementor ACW classes.
These Java ACWs contain 'implements BaseOnChangeListener' which gives R8 a
concrete Java reference — preventing it from stripping the types at link time.

The implements chain from typed sub-interfaces (Slider.OnChangeListener etc.)
to the base interfaces is still broken to prevent ACW erasure clash (#1482).
The auto-generated add/remove methods on BaseSlider are still removed and
replaced with hand-written typed overloads in Additions.

This hybrid approach provides:
- Typed API: AddOnChangeListener(Slider.IOnChangeListener) as Android recommends
- No erasure clash: implements chain broken between typed and base interfaces
- R8 safe: Implementor ACWs reference base types in Java — no ProGuard needed
- Events: Change/StartTrackingTouch/StopTrackingTouch hand-written in Additions

Fixes #1501
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.

Xamarin.Google.Android.Material 1.14.0.3 generates invalid Java implementors for Material slider listener interfaces

3 participants