material-components/material-components-android · error · IllegalStateException
Scroll bar must contain a child to calculate interpolation.
Error message
Scroll bar must contain a child to calculate interpolation.
What it means
InterpolateOnScrollPositionChangeHelper.updateInterpolationForScreenPosition() throws IllegalStateException when the tracked ScrollView exists but has zero children. The helper computes corner 'healing/growing' interpolation from the offset between the ScrollView and its first child; with no child, childAt(0) would NPE, so the library throws a descriptive state exception instead.
Source
Thrown at lib/java/com/google/android/material/shape/InterpolateOnScrollPositionChangeHelper.java:107
* @param viewTreeObserver {@link ViewTreeObserver belonging to the {@link View} being
* interpolated.
*/
public void stopListeningForScrollChanges(@NonNull ViewTreeObserver viewTreeObserver) {
viewTreeObserver.removeOnScrollChangedListener(scrollChangedListener);
}
/**
* Updates the {@link MaterialShapeDrawable}'s interpolation based on the {@link View}'s position
* in the containing {@link ScrollView}.
*/
public void updateInterpolationForScreenPosition() {
if (containingScrollView == null) {
// No scroll view, no healing/growing.
return;
}
if (containingScrollView.getChildCount() == 0) {
// No container inside scroll view, no healing/growing.
throw new IllegalStateException(
"Scroll bar must contain a child to calculate interpolation.");
}
containingScrollView.getLocationInWindow(scrollLocation);
containingScrollView.getChildAt(0).getLocationInWindow(containerLocation);
int y = shapedView.getTop() - scrollLocation[1] + containerLocation[1];
int viewHeight = shapedView.getHeight();
int windowHeight = containingScrollView.getHeight();
// Off the top of the screen.
if (y < 0) {
materialShapeDrawable.setInterpolation(
Math.max(0f, Math.min(1f, 1f + (float) y / (float) viewHeight)));
shapedView.invalidate();
} else if (y + viewHeight > windowHeight) {
int distanceOffScreen = y + viewHeight - windowHeight;
materialShapeDrawable.setInterpolation(
Math.max(0f, Math.min(1f, 1f - (float) distanceOffScreen / (float) viewHeight)));View on GitHub (pinned to ac7e18efee)
Solutions
- Ensure the ScrollView always keeps exactly one container child (a vertical LinearLayout) and swap that container's children instead of removing the container.
- Defer attaching the scroll-position listener until the ScrollView content is inflated.
- Remove the listener (or null the helper's scroll view reference) before clearing scroll content.
Example fix
<!-- before -->
<ScrollView android:id="@+id/scroll">
<!-- children swapped dynamically, sometimes empty -->
</ScrollView>
<!-- after -->
<ScrollView android:id="@+id/scroll">
<LinearLayout android:id="@+id/scrollContent">
<!-- swap children inside this container; container never removed -->
</LinearLayout>
</ScrollView> Defensive patterns
Strategy: validation
Validate before calling
if (scrollView.getChildCount() > 0) {
helper.updateInterpolationForScreenPosition();
} Prevention
- Keep exactly one non-removable container child inside every ScrollView used with corner interpolation.
- Register scroll listeners after content inflation completes.
- Clear listeners when tearing down dynamic content.
When it happens
Trigger: Calling setUpdateAccessibilityNotificationType... no — attaching MaterialShapeDrawable interpolation tracking via view.setOnScrollChangeListener / updateInterpolationForScreenPosition() against a ScrollView whose content was removed (e.g. during a swap or before content loads).
Common situations: Corner-treated cards inside a ScrollView whose child is replaced dynamically and briefly removed; calling the update before setContentView/inflation completes; viewpager fragment where the scroll content is cleared on destroy and a pending scroll callback still fires.
Related errors
- Attempted to set ShapeAppearanceModel on a MaterialButton wh
- Attempted to get ShapeAppearanceModel from a MaterialButton
- Attempted to set ShapeAppearance on a MaterialButton which h
- Attempted to get ShapeAppearance from a MaterialButton which
- Cannot change indeterminate animation type while the progres
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/0edf4ad557876f98.
Report an issue: GitHub.