Summary
The Material 3 pull-to-refresh state-holder surface is bound (AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState, PullToRefreshDefaults), but the @Composable PullToRefreshBox(...) function — the actual entry point users need — is not reachable from C#. The PullToRefreshKt wrapper class is bound as an empty container with zero static methods.
This makes the entire pull-to-refresh feature non-functional from bound API alone.
Library / NuGet
Verified state today (commit eb2f50b)
source/androidx.compose.material3/material3-android/PublicAPI/PublicAPI.Unshipped.txt contains the following pulltorefresh package surface:
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState.AnimateToHidden(Kotlin.Coroutines.IContinuation! p0) -> Java.Lang.Object?
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState.AnimateToThreshold(Kotlin.Coroutines.IContinuation! p0) -> Java.Lang.Object?
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState.DistanceFraction.get -> float
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState.IsAnimating.get -> bool
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState.SnapTo(float targetValue, Kotlin.Coroutines.IContinuation! p1) -> Java.Lang.Object?
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.Elevation.get -> float
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.GetContainerColor(AndroidX.Compose.Runtime.IComposer? _composer, int _changed) -> long
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.GetIndicatorColor(AndroidX.Compose.Runtime.IComposer? _composer, int _changed) -> long
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.GetIndicatorContainerColor(AndroidX.Compose.Runtime.IComposer? _composer, int _changed) -> long
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.IndicatorMaxDistance.get -> float
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.LoadingIndicatorElevation.get -> float
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshDefaults.PositionalThreshold.get -> float
AndroidX.Compose.Material3.PullToRefresh.PullToRefreshKt
Note how PullToRefreshKt is the last line of its block, with no static method members. The Kotlin source exposes:
@Composable
@ExperimentalMaterial3Api
fun PullToRefreshBox(
isRefreshing: Boolean,
onRefresh: () -> Unit,
modifier: Modifier = Modifier,
state: PullToRefreshState = rememberPullToRefreshState(),
contentAlignment: Alignment = Alignment.TopStart,
indicator: @Composable BoxScope.() -> Unit = { … },
content: @Composable BoxScope.() -> Unit,
)
@Composable @ExperimentalMaterial3Api fun rememberPullToRefreshState(): PullToRefreshState
@ExperimentalMaterial3Api
@Composable
fun PullToRefreshDefaults.Indicator(state, isRefreshing, modifier, containerColor, color, threshold)
@ExperimentalMaterial3Api
@Composable
fun PullToRefreshDefaults.LoadingIndicator(state, isRefreshing, modifier, containerColor, color, elevation)
All four of these (PullToRefreshBox, rememberPullToRefreshState, PullToRefreshDefaults.Indicator, PullToRefreshDefaults.LoadingIndicator) carry @JvmInline value class parameters (Modifier, Alignment, Color, Dp) and have hash-mangled JVM names (e.g. PullToRefreshBox-LP5b{hash}), so they are dropped by the same binder pipeline issue as the rest of material3's @Composables.
Metadata.xml today
source/androidx.compose.material3/material3-android/Transforms/Metadata.xml contains only one strip (MaterialTheme.getMotionScheme); there is no explicit <remove-node> for any of the PullToRefresh* methods. They are dropped automatically by the binder due to the inline-class mangling.
Reproduction / evidence
compose-net has not yet implemented a [ComposeBridge] for PullToRefreshBox precisely because it is blocked on the same upstream fix. The compose-net tracking issue is jonathanpeppers/compose-net#53.
A hand-written JNI bridge would be feasible (the underlying Java methods exist and are callable via androidx/compose/material3/pulltorefresh/PullToRefreshKt.PullToRefreshBox-<hash>), but that workaround should not be needed once the binder is fixed.
Suggested fix
This is a downstream effect of dotnet/java-interop#1440. When that PR ships and the binder stops dropping @JvmInline value class overloads with mangled names, every PullToRefresh* @Composable should bind automatically with no Metadata.xml changes required.
This issue is filed primarily as a tracking issue so the regression in user-facing material3 surface is visible. No action needed in the android-libraries repo itself until #1440 lands; at that point a re-binding pass should confirm the methods appear.
Cross-references
Summary
The Material 3 pull-to-refresh state-holder surface is bound (
AndroidX.Compose.Material3.PullToRefresh.IPullToRefreshState,PullToRefreshDefaults), but the@ComposablePullToRefreshBox(...)function — the actual entry point users need — is not reachable from C#. ThePullToRefreshKtwrapper class is bound as an empty container with zero static methods.This makes the entire pull-to-refresh feature non-functional from bound API alone.
Library / NuGet
androidx.compose.material3:material3-android(pulltorefresh lives in the main material3 artifact; there is no separate AAR for it)Xamarin.AndroidX.Compose.Material3.Androidsource/androidx.compose.material3/material3-android/Verified state today (commit eb2f50b)
source/androidx.compose.material3/material3-android/PublicAPI/PublicAPI.Unshipped.txtcontains the followingpulltorefreshpackage surface:Note how
PullToRefreshKtis the last line of its block, with no static method members. The Kotlin source exposes:All four of these (
PullToRefreshBox,rememberPullToRefreshState,PullToRefreshDefaults.Indicator,PullToRefreshDefaults.LoadingIndicator) carry@JvmInline value classparameters (Modifier,Alignment,Color,Dp) and have hash-mangled JVM names (e.g.PullToRefreshBox-LP5b{hash}), so they are dropped by the same binder pipeline issue as the rest of material3's@Composables.Metadata.xml today
source/androidx.compose.material3/material3-android/Transforms/Metadata.xmlcontains only one strip (MaterialTheme.getMotionScheme); there is no explicit<remove-node>for any of thePullToRefresh*methods. They are dropped automatically by the binder due to the inline-class mangling.Reproduction / evidence
compose-nethas not yet implemented a[ComposeBridge]forPullToRefreshBoxprecisely because it is blocked on the same upstream fix. The compose-net tracking issue is jonathanpeppers/compose-net#53.A hand-written JNI bridge would be feasible (the underlying Java methods exist and are callable via
androidx/compose/material3/pulltorefresh/PullToRefreshKt.PullToRefreshBox-<hash>), but that workaround should not be needed once the binder is fixed.Suggested fix
This is a downstream effect of dotnet/java-interop#1440. When that PR ships and the binder stops dropping
@JvmInline value classoverloads with mangled names, everyPullToRefresh*@Composableshould bind automatically with no Metadata.xml changes required.This issue is filed primarily as a tracking issue so the regression in user-facing material3 surface is visible. No action needed in the
android-librariesrepo itself until #1440 lands; at that point a re-binding pass should confirm the methods appear.Cross-references