yuliskov/SmartTube · error · IllegalArgumentException

Callback may not be null

Error message

Callback may not be null

What it means

ViewDragHelper's constructor also requires a non-null Callback — the callback supplies every drag decision (tryCaptureView, clampViewPosition, onViewReleased, ...), so a helper without one cannot function and the constructor throws IllegalArgumentException('Callback may not be null').

Source

Thrown at slidableactivity/src/main/java/com/r0adkll/slidr/util/ViewDragHelper.java:345

        final ViewDragHelper helper = create(forParent, cb);
        helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity));
        return helper;
    }

    /**
     * Apps should use ViewDragHelper.create() to get a new instance.
     * This will allow VDH to use internal compatibility implementations for different
     * platform versions.
     *
     * @param context   Context to initialize config-dependent params from
     * @param forParent Parent view to monitor
     */
    private ViewDragHelper(Context context, ViewGroup forParent, Callback cb) {
        if (forParent == null) {
            throw new IllegalArgumentException("Parent view may not be null");
        }
        if (cb == null) {
            throw new IllegalArgumentException("Callback may not be null");
        }
        mParentView = forParent;
        mCallback = cb;
        final ViewConfiguration vc = ViewConfiguration.get(context);
        final float density = context.getResources().getDisplayMetrics().density;
        mEdgeSize = (int) (EDGE_SIZE * density + 0.5f);
        mTouchSlop = vc.getScaledTouchSlop();
        mMaxVelocity = vc.getScaledMaximumFlingVelocity();
        mMinVelocity = vc.getScaledMinimumFlingVelocity();
        mScroller = ScrollerCompat.create(context, sInterpolator);
    }

    /**
     * Set the minimum velocity that will be detected as having a magnitude greater than zero
     * in pixels per second. Callback methods accepting a velocity will be clamped appropriately.
     *
     * @param minVel Minimum velocity to detect
     */

View on GitHub (pinned to 3de8d90593)

Solutions

  1. Construct the Callback before ViewDragHelper.create() and pass the same instance.
  2. Reorder initialization so the callback field is assigned first, or inline the anonymous/lambda callback in the create() call.
  3. In Kotlin, make the callback a val initialized at declaration or pass it as a constructor parameter so it can never be null at create() time.

Example fix

// before
private ViewDragHelper mHelper;
private MyDragCallback mCallback; // still null here
void setup() {
    mHelper = ViewDragHelper.create(this, parent, mCallback); // throws
    mCallback = new MyDragCallback();
}

// after
void setup() {
    mCallback = new MyDragCallback();
    mHelper = ViewDragHelper.create(this, parent, mCallback);
}
Defensive patterns

Strategy: validation

Validate before calling

if (mCallback != null) {
    mHelper = ViewDragHelper.create(this, parent, mCallback);
} else {
    Log.e(TAG, "drag callback not initialized before create()");
}

Prevention

When it happens

Trigger: ViewDragHelper.create(context, parent, null): commonly a callback field not yet assigned when create() runs (ordering bug in initialization), an anonymous callback accidentally not constructed, or a Kotlin property still null at call time.

Common situations: The helper is created in the constructor but the callback is assigned later in onCreate/onViewCreated; refactoring moved callback construction after create(); subclasses forgetting to pass their callback through.

Related errors


AI-assisted analysis of yuliskov/SmartTube@3de8d90593 (2026-08-22). Data as JSON: /api/errors/68364c5f5007c699. Report an issue: GitHub.