material-components/material-components-android · error · IllegalStateException
Unexpected tickVisibilityMode:
Error message
Unexpected tickVisibilityMode:
What it means
IllegalStateException thrown by isTickVisible() when tickVisibilityMode holds a value outside the known set (TICK_VISIBILITY_AUTO_LIMIT, AUTO_HIDE, HIDDEN). This is the switch's default arm; in normal operation the constants are @IntDef-annotated, so reaching it means an unannotated int was forced into the mode.
Source
Thrown at lib/java/com/google/android/material/slider/BaseSlider.java:1938
inactiveTicksPaint.setColor(getColorForState(tickColorInactive));
invalidate();
}
/**
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
*
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
*/
public boolean isTickVisible() {
switch (tickVisibilityMode) {
case TICK_VISIBILITY_AUTO_LIMIT:
return true;
case TICK_VISIBILITY_AUTO_HIDE:
return getDesiredTickCount() <= getMaxTickCount();
case TICK_VISIBILITY_HIDDEN:
return false;
default:
throw new IllegalStateException("Unexpected tickVisibilityMode: " + tickVisibilityMode);
}
}
/**
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
*
* @param tickVisible The visibility of tick marks.
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
* @deprecated Use {@link #setTickVisibilityMode(int)} instead.
*/
@Deprecated
public void setTickVisible(boolean tickVisible) {
setTickVisibilityMode(convertToTickVisibilityMode(tickVisible));
}
@TickVisibilityMode
private int convertToTickVisibilityMode(boolean tickVisible) {
return tickVisible ? TICK_VISIBILITY_AUTO_LIMIT : TICK_VISIBILITY_HIDDEN;View on GitHub (pinned to ac7e18efee)
Solutions
- Only pass Slider.TICK_VISIBILITY_* constants to setTickVisibilityMode.
- Validate restored ints against the known set before applying, defaulting to TICK_VISIBILITY_AUTO_HIDE.
- Keep the annotation processor / lint IntDef checks enabled so bad ints are caught at compile time.
Example fix
// before
slider.setTickVisibilityMode(modeFromPrefs); // arbitrary int -> may throw later
// after
int mode = (modeFromPrefs == Slider.TICK_VISIBILITY_AUTO_LIMIT
|| modeFromPrefs == Slider.TICK_VISIBILITY_AUTO_HIDE
|| modeFromPrefs == Slider.TICK_VISIBILITY_HIDDEN)
? modeFromPrefs : Slider.TICK_VISIBILITY_AUTO_HIDE;
slider.setTickVisibilityMode(mode); Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidTickVisibilityMode(int m) {
return m == Slider.TICK_VISIBILITY_AUTO_LIMIT
|| m == Slider.TICK_VISIBILITY_AUTO_HIDE
|| m == Slider.TICK_VISIBILITY_HIDDEN;
}
slider.setTickVisibilityMode(isValidTickVisibilityMode(m) ? m : Slider.TICK_VISIBILITY_AUTO_HIDE); Prevention
- Pass only TICK_VISIBILITY_* constants; keep @IntDef lint active.
- Persist modes as stable strings, map back to constants on read.
When it happens
Trigger: Calling setTickVisibilityMode(rawInt) with an int not in the IntDef set (e.g. from a bundle, deep link parameter, or prefs) then invoking isTickVisible(); reflection or cross-version constant mismatches after downgrading the library.
Common situations: Persisting the visibility mode as an int and restoring it after a library downgrade where constant values shifted; passing mode values through untyped channels (Intent extras, JSON).
Related errors
- Unexpected labelBehavior:
- Not enough labels(%d) to display all the values(%d)
- The stepSize(%s) must be 0, or a factor of the valueFrom(%s)
- valueFrom(%s) must be smaller than valueTo(%s)
- Slider value(%s) must be greater or equal to valueFrom(%s),
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/014d6bba22f00f39.
Report an issue: GitHub.