yuliskov/SmartTube · error · IllegalStateException
Cannot flingCapturedView outside of a call to Callback#onVie
Error message
Cannot flingCapturedView outside of a call to Callback#onViewReleased
What it means
flingCapturedView() applies a velocity-based fling to the currently captured view using the velocities the helper measured during the drag. Like settleCapturedViewAt, it is only legal while mReleaseInProgress is true — i.e., inside Callback#onViewReleased — and throws IllegalStateException anywhere else.
Source
Thrown at slidableactivity/src/main/java/com/r0adkll/slidr/util/ViewDragHelper.java:650
private float distanceInfluenceForSnapDuration(float f) {
f -= 0.5f; // center the values about 0.
f *= 0.3f * Math.PI / 2.0f;
return (float) Math.sin(f);
}
/**
* Settle the captured view based on standard free-moving fling behavior.
* The caller should invoke {@link #continueSettling(boolean)} on each subsequent frame
* to continue the motion until it returns false.
*
* @param minLeft Minimum X position for the view's left edge
* @param minTop Minimum Y position for the view's top edge
* @param maxLeft Maximum X position for the view's left edge
* @param maxTop Maximum Y position for the view's top edge
*/
public void flingCapturedView(int minLeft, int minTop, int maxLeft, int maxTop) {
if (!mReleaseInProgress) {
throw new IllegalStateException("Cannot flingCapturedView outside of a call to " +
"Callback#onViewReleased");
}
mScroller.fling(mCapturedView.getLeft(), mCapturedView.getTop(),
(int) VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId),
(int) VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId),
minLeft, maxLeft, minTop, maxTop);
setDragState(STATE_SETTLING);
}
/**
* Move the captured settling view by the appropriate amount for the current time.
* If <code>continueSettling</code> returns true, the caller should call it again
* on the next frame to continue.
*
* @param deferCallbacks true if state callbacks should be deferred via posted message.
* Set this to true if you are calling this method from
* {@link android.view.View#computeScroll()} or similar methods
* invoked as part of layout or drawing.View on GitHub (pinned to 3de8d90593)
Solutions
- Move flingCapturedView into Callback#onViewReleased, computing min/max bounds there.
- For programmatic dismissal outside a release, use smoothSlideViewTo(child, finalLeft, finalTop) plus continueSettling(true) per frame instead.
- If you need fling physics outside a release, compute the target yourself and settle with smoothSlideViewTo.
Example fix
// before
void dismissProgrammatically() {
mDragHelper.flingCapturedView(0, 0, getWidth(), getHeight()); // throws outside release
}
// after
void dismissProgrammatically() {
mDragHelper.smoothSlideViewTo(mDraggableChild, mParentView.getWidth(), mDraggableChild.getTop());
ViewCompat.postInvalidateOnAnimation(mParentView);
}
@Override public void onViewReleased(View child, float xvel, float yvel) {
mDragHelper.flingCapturedView(0, 0, mParentView.getWidth(), mParentView.getHeight());
ViewCompat.postInvalidateOnAnimation(mParentView);
} Defensive patterns
Strategy: validation
Validate before calling
// fling is legal only inside onViewReleased
@Override
public void onViewReleased(View child, float xvel, float yvel) {
mDragHelper.flingCapturedView(0, 0, mParentView.getWidth(), mParentView.getHeight());
ViewCompat.postInvalidateOnAnimation(mParentView);
}
// programmatic dismiss path (outside release):
mDragHelper.smoothSlideViewTo(child, mParentView.getWidth(), child.getTop());
ViewCompat.postInvalidateOnAnimation(mParentView); Prevention
- flingCapturedView and settleCapturedViewAt share the same release-window rule.
- Route dismiss/close buttons through smoothSlideViewTo, not fling/settle.
- Re-check any ported Scroller code for calls made outside onViewReleased.
When it happens
Trigger: Calling flingCapturedView(...) from any code other than the onViewReleased override: dismiss buttons, timers, chained animations, or helper classes that trigger flings on their own schedule.
Common situations: Implementing slide-to-dismiss with an extra programmatic dismiss trigger; refactoring release logic into a separate class that calls fling directly; mimicking bottom-sheet behavior outside the release callback.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot settleCapturedViewAt outside of a call to Callback#on
- Parent view may not be null
- Callback may not be null
- captureChildView: parameter must be a descendant of the View
- 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/1c5f9ce48a8216a2.
Report an issue: GitHub.