umano/AndroidSlidingUpPanel · error · java.lang.IllegalArgumentException

Callback may not be null

Error message

Callback may not be null

What it means

A validation guard in ViewDragHelper's private constructor: it rejects a null Callback parameter. The Callback is essential — ViewDragHelper delegates all drag behavior (which child can be dragged, clamp positions, onDrag/onRelease notifications) to it, so a helper without one is unusable and would NPE later during touch events. It fires when a caller passes null for the cb argument, e.g. calling the private constructor directly or a factory wrapper that forwards an uninitialized callback. Note the constructor is private by design; apps must use ViewDragHelper.create(), which always requires a non-null Callback. Fix: pass a real Callback subclass instance (e.g. a ViewDragHelper.Callback overriding tryCaptureView).

Solutions

  1. Pass a concrete Callback implementation to create()
  2. Construct the callback inline or before helper creation
  3. Verify initialization order of fields

Example fix

// before
mDragHelper = ViewDragHelper.create(this, mCallback); // mCallback is null
// after
mDragHelper = ViewDragHelper.create(this, new ViewDragHelper.Callback() { ... });
Defensive patterns

Strategy: type-guard

Validate before calling

if (callback == null) throw new AssertionError("callback required");
mDragHelper = ViewDragHelper.create(this, callback);

Type guard

ViewDragHelper.Callback requireCb(ViewDragHelper.Callback cb) { return cb != null ? cb : defaultCallback; }

Prevention

When it happens

Trigger: Calling ViewDragHelper.create(parent, null) or passing a callback field that is still null (e.g. set later in a lifecycle callback that hasn't run).

Common situations: Kotlin lateinit/Java field callbacks not yet assigned; refactoring where the callback was removed but the create call retained the now-null reference.

Related errors


AI-assisted analysis of umano/AndroidSlidingUpPanel@45a460435b (2026-09-11). Data as JSON: /api/errors/be8ff6eeb4d7e967. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/sothree/slidinguppanel/ViewDragHelper.java:409

        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.
     * If the interpolator is null, the default interpolator will be used.
     *
     * @param context Context to initialize config-dependent params from
     * @param forParent Parent view to monitor
     * @param interpolator interpolator for scroller
     */
    private ViewDragHelper(Context context, ViewGroup forParent, Interpolator interpolator, 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, interpolator != null ? interpolator : 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.

View on GitHub (pinned to 45a460435b)