yuliskov/SmartTube · error · IllegalArgumentException
captureChildView: parameter must be a descendant of the View
Error message
captureChildView: parameter must be a descendant of the ViewDragHelper's tracked parent view (${mParentView}) What it means
captureChildView(view, pointerId) forcibly starts dragging a view without asking Callback#tryCaptureView. ViewDragHelper tracks exactly one parent ViewGroup, and the target's immediate parent (childView.getParent()) must be that exact view, otherwise IllegalArgumentException. Note getParent() returns the direct parent, so grandchildren of the tracked container fail the check too.
Source
Thrown at slidableactivity/src/main/java/com/r0adkll/slidr/util/ViewDragHelper.java:426
*
* @return The size of an edge in pixels
* @see #setEdgeTrackingEnabled(int)
*/
public int getEdgeSize() {
return mEdgeSize;
}
/**
* Capture a specific child view for dragging within the parent. The callback will be notified
* but {@link Callback#tryCaptureView(android.view.View, int)} will not be asked permission to
* capture this view.
*
* @param childView Child view to capture
* @param activePointerId ID of the pointer that is dragging the captured child view
*/
public void captureChildView(View childView, int activePointerId) {
if (childView.getParent() != mParentView) {
throw new IllegalArgumentException("captureChildView: parameter must be a descendant " +
"of the ViewDragHelper's tracked parent view (" + mParentView + ")");
}
mCapturedView = childView;
mActivePointerId = activePointerId;
mCallback.onViewCaptured(childView, activePointerId);
setDragState(STATE_DRAGGING);
}
/**
* @return The currently captured view, or null if no view has been captured.
*/
public View getCapturedView() {
return mCapturedView;
}
/**
* @return The ID of the pointer currently dragging the captured view,
* or {@link #INVALID_POINTER}.View on GitHub (pinned to 3de8d90593)
Solutions
- Create the ViewDragHelper on the immediate parent of the view you intend to capture.
- Capture the direct child and let the callback decide how nested content moves, rather than capturing a grandchild.
- Guard the call: if (child.getParent() == trackedParent) helper.captureChildView(child, pointerId).
- When the target really is nested, capture its ancestor that is a direct child and translate motion in your callback.
Example fix
// before
mHelper.captureChildView(rowLabel, pointerId); // rowLabel is a grandchild → throws
// after — capture the direct child of the tracked parent
View directChild = (View) rowLabel.getParent(); // card row, direct child of tracked ViewGroup
if (directChild.getParent() == mParentTrackedByHelper) {
mHelper.captureChildView(directChild, pointerId);
} Defensive patterns
Strategy: validation
Validate before calling
void captureIfDirectChild(View target, int pointerId) {
if (target != null && mParentTracked.equals(target.getParent())) {
mHelper.captureChildView(target, pointerId);
} else {
// walk up to the direct child of the tracked parent
View p = target;
while (p != null && !mParentTracked.equals(p.getParent())) {
p = (View) p.getParent();
}
if (p != null) mHelper.captureChildView(p, pointerId);
}
} Prevention
- Create ViewDragHelper on the immediate parent of the views you capture.
- Remember getParent() is the DIRECT parent — grandchildren fail the check.
- Check target.getParent() == trackedParent before every captureChildView call.
When it happens
Trigger: Passing a nested descendant (e.g., a label two levels inside a card row) instead of a direct child of the ViewGroup given to ViewDragHelper.create(); passing a view from another hierarchy or a view not yet attached (getParent() is null).
Common situations: Custom leanback/card layouts where the touch target sits deeper than the tracked container; creating the helper on the window decor but capturing an inner panel; RecyclerView children whose parent is the RecyclerView while the helper tracks its parent; view recycling swapping parents between checks.
Related errors
- Parent view may not be null
- Callback may not be null
- Cannot settleCapturedViewAt outside of a call to Callback#on
- Cannot flingCapturedView outside of a call to Callback#onVie
- You can't set adapter to DialogsList. Use #setAdapter(Dialog
AI-assisted analysis of yuliskov/SmartTube@3de8d90593 (2026-08-22).
Data as JSON: /api/errors/762783393976acff.
Report an issue: GitHub.