Baseflow/PhotoView · error · IllegalArgumentException
Medium zoom has to be less than Maximum zoom. Call setMaximu
Error message
Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value
What it means
Util.checkZoomLevels enforces minimumScale < mediumScale < maximumScale; this branch throws IllegalArgumentException when midZoom >= maxZoom, from setMediumScale, setMaximumScale, or setScaleLevels. PhotoView's double-tap handler cycles min -> mid -> max (see setScale(getMediumScale()/getMaximumScale()) in the attacher's onDoubleTap), which requires medium strictly below maximum. The check runs before assignment, so previous valid levels survive the failed call.
Source
Thrown at photoview/src/main/java/com/github/chrisbanes/photoview/Util.java:14
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");
}
return true;
}View on GitHub (pinned to 565505d5cb)
Solutions
- Set all three at once with setScaleLevels(min, mid, max) keeping mid strictly less than max (e.g. setScaleLevels(1f, 2f, 3f)).
- When lowering max, lower mid proportionally first (or in the same call): max = 2f implies mid <= something strictly below 2f, e.g. mid = max * 0.66f.
- If levels are dynamic, derive them from one base: min = base, mid = base * 1.75f, max = base * 3f, so ordering can never collapse.
Example fix
// before photoView.setMaximumScale(1.5f); // throws: mid (2.0) >= max (1.5) // after photoView.setScaleLevels(1f, 1.2f, 1.5f);
Defensive patterns
Strategy: validation
Validate before calling
if (mediumScale < maximumScale
&& minimumScale < mediumScale) {
photoView.setScaleLevels(minimumScale, mediumScale, maximumScale);
} else {
// derive ordered levels from a single base
photoView.setScaleLevels(base, base * 1.75f, base * 3f);
} Prevention
- Derive mid and max from one base multiplier (mid = base * 1.75f, max = base * 3f) so equality/inversion is impossible.
- Review any screen that lowers maximumScale for accompanying mediumScale changes.
- Cover zoom-level configuration with a unit test asserting min < mid < max for all computed inputs.
When it happens
Trigger: Calling setMaximumScale(2f) while mediumScale is 2.0 or higher (e.g. default mid 2.0 with new max 2.0 -> 2 >= 2 throws); calling setMediumScale(3f) while max is still 3.0; setScaleLevels(1f, 2.5f, 2f) with mid above max.
Common situations: Lowering maximum zoom for a detail-view screen without also lowering medium; computing medium from image resolution so it exceeds a deliberately small max; setting medium before max during init and picking values that collide at equality; porting constants between screens where max was tuned per-layout but mid is a shared constant.
Related errors
- Minimum zoom has to be less than Medium zoom. Call setMinimu
- 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/c75a311489ca3747.
Report an issue: GitHub.