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
- Use only LinearSmoothScroller.SNAP_TO_START, SNAP_TO_END, or SNAP_TO_END/SNAP_TO_ANY.
- When overriding calculateDtToFit, ensure snapPreference passed to super is one of the three constants.
- 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 subclassing LinearSmoothScroller, pass only the framework SNAP_* constants to calculateDtToFit.
- Avoid reusing Gravity or custom flags as snap preferences.
- Override calculateDtToFit entirely if you need non-standard snapping.
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
- Must pass a ViewHolder when dragging
- invalid orientation:{}
- invalid orientation
- {index} is an invalid index for size {size}
- Invalid direction: {direction}
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/37105923d1d0a069.
Report an issue: GitHub.