Baseflow/PhotoView · error · IllegalArgumentException
Minimum zoom has to be less than Medium zoom. Call setMinimu
Error message
Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value
What it means
Util.checkZoomLevels enforces the invariant minimumScale < mediumScale < maximumScale and throws IllegalArgumentException from setMinimumScale, setMediumScale, setMaximumScale, or setScaleLevels when minZoom >= midZoom. PhotoView's double-tap and zoom gesture logic assumes a strictly increasing ordering, so a flat or inverted range would make double-tap cycles undefined. The exception fires before any state is mutated, so the attacher keeps its previous valid levels.
Source
Thrown at photoview/src/main/java/com/github/chrisbanes/photoview/Util.java:11
package com.github.chrisbanes.photoview;
import android.view.MotionEvent;
import android.widget.ImageView;
class Util {
static void checkZoomLevels(float minZoom, float midZoom,
float maxZoom) {
if (minZoom >= midZoom) {
throw new IllegalArgumentException(
"Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value");
} else if (midZoom >= maxZoom) {
throw new IllegalArgumentException(
"Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value");
}
}
static boolean hasDrawable(ImageView imageView) {
return imageView.getDrawable() != null;
}
static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) {
if (scaleType == null) {
return false;
}
switch (scaleType) {
case MATRIX:
throw new IllegalStateException("Matrix scale type is not supported");View on GitHub (pinned to 565505d5cb)
Solutions
- Set all three levels atomically with setScaleLevels(min, mid, max) in strictly increasing order, instead of sequencing individual setters.
- If levels are computed from image size, clamp/order them before applying: ensure min < mid < max, e.g. min = Math.min(min, mid / 2f).
- Reorder initialization so setMinimumScale runs before setMediumScale/setMaximumScale, and make each new value respect the levels already set.
Example fix
// before
photoView.setMinimumScale(fitScale); // throws when fitScale >= midScale
// after
photoView.setScaleLevels(
Math.min(fitScale, DEFAULT_MID / 2f),
Math.max(fitScale * 1.5f, DEFAULT_MID),
Math.max(fitScale * 3f, DEFAULT_MAX)); Defensive patterns
Strategy: validation
Validate before calling
float min = Math.min(minScale, midScale * 0.5f); float mid = Math.max(midScale, min * 1.5f); // keep mid < max by construction before any setter runs photoView.setScaleLevels(min, mid, Math.max(maxScale, mid * 1.5f));
Prevention
- Always configure all three levels in one setScaleLevels(min, mid, max) call instead of sequencing individual setters.
- When levels are computed from drawable size, assert min < mid < max in debug builds (assert mid > min && max > mid).
- Order setters min -> mid -> max if you must set them individually, and make each value strictly greater than the previous.
When it happens
Trigger: Calling photoView.setMinimumScale(2f) while mediumScale is still 2.0 (default) — 2 >= 2 throws; calling setScaleLevels(1f, 1f, 3f) with min equal to mid; calling setScaleLevels(1.5f, 1.2f, 3f) with min greater than mid; any per-level setter whose new value crosses the adjacent level.
Common situations: Deriving one zoom level from image dimensions (e.g. medium = drawableWidth/viewWidth) while leaving others hardcoded, so medium ends up <= min (a large image in a small view gives medium < 1.0 while min stays 1.0); ordering setMinimumScale/setMediumScale calls wrongly during initialization (setting min after mid); migrating from an older PhotoView version where level checks were looser.
Related errors
- Medium zoom has to be less than Maximum zoom. Call setMaximu
- Matrix cannot be null
- Scale must be within the range of minScale and maxScale
- Matrix scale type is not supported
AI-assisted analysis of Baseflow/PhotoView@565505d5cb (2026-08-14).
Data as JSON: /api/errors/3ef0b237cc03c4b4.
Report an issue: GitHub.