unoplatform/uno · error · IllegalStateException

UnoTwoDScrollView can host only one direct child

Error message

UnoTwoDScrollView can host only one direct child

What it means

Thrown by UnoTwoDScrollView.addView(View child) when getChildCount() is already greater than zero. UnoTwoDScrollView (like Android's ScrollView/HorizontalScrollView) enforces a single direct child — a container that wraps the scrollable content. Adding a second direct child violates this invariant.

Source

Thrown at src/Uno.UI.BindingHelper.Android/Uno/UI/UnoTwoDScrollView.java:235

	private void initTwoDScrollView() {
		mScroller = new OverScroller(getContext());
		setFocusable(true);
		setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
		setWillNotDraw(false);
		final ViewConfiguration configuration = ViewConfiguration.get(getContext());
		mTouchSlop = configuration.getScaledTouchSlop();
		mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
		mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
		mOverscrollDistance = configuration.getScaledOverscrollDistance();
		mOverflingDistance = configuration.getScaledOverflingDistance();

		mscaleGestureDetector = new UnoScrollViewScaleGestureDetector(getContext(), new UnoScrollViewScaleGestureDetector.UnoScaleGestureListener(this));
	}

	@Override
	public void addView(View child) {
		if (getChildCount() > 0) {
			throw new IllegalStateException("UnoTwoDScrollView can host only one direct child");
		}
		super.addView(child);
	}

	@Override
	public void addView(View child, int index) {
		if (getChildCount() > 0) {
			throw new IllegalStateException("UnoTwoDScrollView can host only one direct child");
		}
		super.addView(child, index);
	}

	@Override
	public void addView(View child, ViewGroup.LayoutParams params) {
		if (getChildCount() > 0) {
			throw new IllegalStateException("UnoTwoDScrollView can host only one direct child");
		}
		super.addView(child, params);

View on GitHub (pinned to 0418340488)

Solutions

  1. Wrap all scroll content in a single container (Grid, StackPanel, etc.) and set that container as the only child of the ScrollView.
  2. If adding children dynamically, always add to the inner content panel, not the ScrollView itself.

Example fix

// before: two direct children
scrollView.addView(childA);
scrollView.addView(childB); // throws

// after: single wrapper child
var wrapper = new LinearLayout(context);
wrapper.addView(childA);
wrapper.addView(childB);
scrollView.addView(wrapper); // single child — OK
Defensive patterns

Strategy: validation

Validate before calling

// Before addView, verify no child exists
if (scrollView.getChildCount() === 0) {
    scrollView.addView(child);
} else {
    // add to the existing single content child instead
}

Try / catch

try {
    scrollView.addView(child);
} catch (e) {
    if (e.getMessage().contains('only one direct child')) {
        // redirect to inner content panel
    } else { throw e; }
}

Prevention

When it happens

Trigger: XAML or code adds more than one child directly to the UnoTwoDScrollView instead of wrapping multiple children in a single container (e.g. a StackPanel/Grid).

Common situations: A XAML layout places two sibling elements directly inside the ScrollView content without a wrapping panel; dynamically calling AddView on the scroll host without checking existing children.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/24fb9274394123b4. Report an issue: GitHub.