DrKLO/Telegram · error · IllegalArgumentException

snap preference should be one of the constants defined in Sm

Error message

snap preference should be one of the constants defined in SmoothScroller, starting with SNAP_

What it means

LinearSmoothScroller.calculateDtToFit() computes the scroll delta to bring a view into the visible box. Its snapPreference switch only handles SNAP_TO_START, SNAP_TO_END, SNAP_TO_ANY. The default branch rejects any other value because the snapping direction is undefined and the math would be arbitrary.

Source

Thrown at TMessagesProj/src/main/java/androidx/recyclerview/widget/LinearSmoothScroller.java:298

    public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int
            snapPreference) {
        switch (snapPreference) {
            case SNAP_TO_START:
                return boxStart - viewStart;
            case SNAP_TO_END:
                return boxEnd - viewEnd;
            case SNAP_TO_ANY:
                final int dtStart = boxStart - viewStart;
                if (dtStart > 0) {
                    return dtStart;
                }
                final int dtEnd = boxEnd - viewEnd;
                if (dtEnd < 0) {
                    return dtEnd;
                }
                break;
            default:
                throw new IllegalArgumentException("snap preference should be one of the"
                        + " constants defined in SmoothScroller, starting with SNAP_");
        }
        return 0;
    }

    /**
     * Calculates the vertical scroll amount necessary to make the given view fully visible
     * inside the RecyclerView.
     *
     * @param view           The view which we want to make fully visible
     * @param snapPreference The edge which the view should snap to when entering the visible
     *                       area. One of {@link #SNAP_TO_START}, {@link #SNAP_TO_END} or
     *                       {@link #SNAP_TO_ANY}.
     * @return The vertical scroll amount necessary to make the view visible with the given
     * snap preference.
     */
    public int calculateDyToMakeVisible(View view, int snapPreference) {
        final RecyclerView.LayoutManager layoutManager = getLayoutManager();

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Use only LinearSmoothScroller.SNAP_TO_START, SNAP_TO_END, or SNAP_TO_END/SNAP_TO_ANY.
  2. When overriding calculateDtToFit, ensure snapPreference passed to super is one of the three constants.
  3. If you need custom snapping, override calculateDtToFit entirely and do not delegate to super with a non-standard value.

Example fix

// before
return calculateDtToFit(vStart, vEnd, bStart, bEnd, 99); // custom flag

// after
return calculateDtToFit(vStart, vEnd, bStart, bEnd, LinearSmoothScroller.SNAP_TO_ANY);
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidSnap(int s) {
    return s == LinearSmoothScroller.SNAP_TO_START
        || s == LinearSmoothScroller.SNAP_TO_END
        || s == LinearSmoothScroller.SNAP_TO_ANY;
}
// only call calculateDtToFit(..., snap) when isValidSnap(snap) is true

Type guard

static boolean isSnapConstant(int s) {
    return s == LinearSmoothScroller.SNAP_TO_START
        || s == LinearSmoothScroller.SNAP_TO_END
        || s == LinearSmoothScroller.SNAP_TO_ANY;
}

Try / catch

null

Prevention

When it happens

Trigger: A subclass overrides calculateDtToFit or calls it directly with an int that is not one of the three SNAP_* constants defined on SmoothScroller. Passing an arbitrary 'gravity'-style flag (e.g. Gravity.CENTER) into calculateDxToMakeVisible/calculateDyToMakeVisible which forward snapPreference.

Common situations: Custom SmoothScroller subclass hard-codes a snap preference constant that drifts from the base constants after a version bump. Reusing a Gravity.* or a custom SNAP_*-like value (e.g. 99) without aligning to the framework constants.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/37105923d1d0a069. Report an issue: GitHub.