Summary
Painter and the painter implementations (BitmapPainter, BrushPainter, ColorPainter) are bound in Xamarin.AndroidX.Compose.UI.Graphics, but the loader painterResource(@DrawableRes id: Int): Painter from androidx.compose.ui.res.PainterResources_androidKt is not reachable from C# — only an empty PainterResources_androidKt wrapper class is emitted, with zero static methods.
Without painterResource, the bound Painter types are unreachable from typical Compose code (Image(painter = painterResource(R.drawable.foo), …)).
Library / NuGet
Verified state today (commit eb2f50b)
source/androidx.compose.ui/ui-android/PublicAPI/PublicAPI.Unshipped.txt contains exactly two PainterResources_androidKt lines:
AndroidX.Compose.UI.Res.PainterResources_androidKt
override AndroidX.Compose.UI.Res.PainterResources_androidKt.JniPeerMembers.get -> Java.Interop.JniPeerMembers!
…i.e. the class wrapper is bound but no painterResource static method is exposed. The Kotlin function is:
@Composable
@ReadOnlyComposable
fun painterResource(@DrawableRes id: Int): Painter
There is no @JvmInline value class parameter, so this is not the same hash-mangled-name pattern as dotnet/java-interop#1440. The @Composable annotation alone causes the JVM signature to include trailing Composer + Int $changed parameters, but those bind fine elsewhere. Something more specific is dropping this overload — likely the @ReadOnlyComposable attribute or the Painter return type's nullability/inheritance metadata.
For comparison, Painter itself binds fine in Xamarin.AndroidX.Compose.UI.Graphics:
AndroidX.Compose.UI.Graphics.Painter.Painter
abstract AndroidX.Compose.UI.Graphics.Painter.Painter.IntrinsicSize.get -> long
virtual AndroidX.Compose.UI.Graphics.Painter.Painter.ApplyAlpha(float alpha) -> bool
virtual AndroidX.Compose.UI.Graphics.Painter.Painter.ApplyColorFilter(AndroidX.Compose.UI.Graphics.ColorFilter? colorFilter) -> bool
…
AndroidX.Compose.UI.Graphics.Painter.BitmapPainter
AndroidX.Compose.UI.Graphics.Painter.BrushPainter
AndroidX.Compose.UI.Graphics.Painter.ColorPainter
Metadata.xml today
source/androidx.compose.ui/ui-android/Transforms/Metadata.xml has surgical removes for inline-class hash-mangled overloads but nothing referencing painterResource / PainterResources_androidKt. The method is being dropped by the binder itself, not by the project's transforms.
Reproduction / evidence
compose-net works around this with a hand-written JNI bridge:
ComposeBridges.cs – [ComposeBridge(Class = "androidx/compose/ui/res/PainterResources_androidKt", JvmName = "painterResource", Signature = "(ILandroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/painter/Painter;")]
The bridge calls successfully at runtime and returns a usable Painter handle, so the underlying Java method exists and behaves correctly — only the binding-time projection is missing.
Suggested fix
Add the painterResource(int, Composer, int) static to AndroidX.Compose.UI.Res.PainterResources_androidKt. If it can't be generated automatically, an add-node transform in Transforms/Metadata.xml should suffice.
Cross-references
Summary
Painterand the painter implementations (BitmapPainter,BrushPainter,ColorPainter) are bound inXamarin.AndroidX.Compose.UI.Graphics, but the loaderpainterResource(@DrawableRes id: Int): Painterfromandroidx.compose.ui.res.PainterResources_androidKtis not reachable from C# — only an emptyPainterResources_androidKtwrapper class is emitted, with zero static methods.Without
painterResource, the boundPaintertypes are unreachable from typical Compose code (Image(painter = painterResource(R.drawable.foo), …)).Library / NuGet
androidx.compose.ui:ui-android(theKtclass lives here, not inui-graphics-android)Xamarin.AndroidX.Compose.UI.Androidsource/androidx.compose.ui/ui-android/Verified state today (commit eb2f50b)
source/androidx.compose.ui/ui-android/PublicAPI/PublicAPI.Unshipped.txtcontains exactly twoPainterResources_androidKtlines:…i.e. the class wrapper is bound but no
painterResourcestatic method is exposed. The Kotlin function is:There is no
@JvmInline value classparameter, so this is not the same hash-mangled-name pattern as dotnet/java-interop#1440. The@Composableannotation alone causes the JVM signature to include trailingComposer+Int $changedparameters, but those bind fine elsewhere. Something more specific is dropping this overload — likely the@ReadOnlyComposableattribute or thePainterreturn type's nullability/inheritance metadata.For comparison,
Painteritself binds fine inXamarin.AndroidX.Compose.UI.Graphics:Metadata.xml today
source/androidx.compose.ui/ui-android/Transforms/Metadata.xmlhas surgical removes for inline-class hash-mangled overloads but nothing referencingpainterResource/PainterResources_androidKt. The method is being dropped by the binder itself, not by the project's transforms.Reproduction / evidence
compose-networks around this with a hand-written JNI bridge:ComposeBridges.cs–[ComposeBridge(Class = "androidx/compose/ui/res/PainterResources_androidKt", JvmName = "painterResource", Signature = "(ILandroidx/compose/runtime/Composer;I)Landroidx/compose/ui/graphics/painter/Painter;")]The bridge calls successfully at runtime and returns a usable
Painterhandle, so the underlying Java method exists and behaves correctly — only the binding-time projection is missing.Suggested fix
Add the
painterResource(int, Composer, int)static toAndroidX.Compose.UI.Res.PainterResources_androidKt. If it can't be generated automatically, anadd-nodetransform inTransforms/Metadata.xmlshould suffice.Cross-references
src/ComposeNet.Compose/Image.cs)painterResourcedoes not appear blocked on Un-strip ui-text-android and ui-unit-android Compose bindings #1440 because it has no inline-class parameters.