Skip to content

[Slider] Fix slider height and side padding #4533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions lib/java/com/google/android/material/math/MathUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
package com.google.android.material.math;

import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;

import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;

/** A class that contains utility methods related to numbers. */
public final class MathUtils {
Expand Down Expand Up @@ -102,6 +105,48 @@ public static int floorMod(int x, int y) {
return x - r * y;
}

/**
* The same as {@link Math#ceilDiv(int, int)}, but for API < 35.
*
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public static int ceilDiv(int x, int y) {
final int q = x / y;
// if the signs are the same and modulo not zero, round up
if ((x ^ y) >= 0 && (q * y != x)) {
return q + 1;
}
return q;
}

/**
* Returns the greater of the given values.
*
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public static int max(final int... array) {
validateArray(array);

int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}

private static void validateArray(final int[] array) {
if (array == null) {
throw new NullPointerException("The array should not be null");
}
if (array.length == 0) {
throw new IllegalArgumentException("The array should not be empty");
}
}

/**
* Returns whether the array contains all same elements.
*
Expand Down
53 changes: 35 additions & 18 deletions lib/java/com/google/android/material/slider/BaseSlider.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
import com.google.android.material.internal.ThemeEnforcement;
import com.google.android.material.internal.ViewOverlayImpl;
import com.google.android.material.internal.ViewUtils;
import com.google.android.material.math.MathUtils;
import com.google.android.material.motion.MotionUtils;
import com.google.android.material.resources.MaterialResources;
import com.google.android.material.shape.MaterialShapeDrawable;
Expand Down Expand Up @@ -646,16 +647,21 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
a.recycle();
}

private boolean maybeIncreaseTrackSidePadding() {
int increasedSidePaddingByThumb = max(thumbWidth / 2 - defaultThumbRadius, 0);
int increasedSidePaddingByTrack = max((trackThickness - defaultTrackThickness) / 2, 0);
int increasedSidePaddingByActiveTick = max(tickActiveRadius - defaultTickActiveRadius, 0);
int increasedSidePaddingByInactiveTick = max(tickInactiveRadius - defaultTickInactiveRadius, 0);
private boolean isSidePaddingChanged() {
int minSideSpaceWidthForThumb = MathUtils.ceilDiv(thumbWidth, 2);
int minSideSpaceWidthForTrack = getTrackCornerSize();
int minSideSpaceWidthForActiveTick = tickActiveRadius;
int minSideSpaceWidthForInactiveTick = tickInactiveRadius;
int minSideSpaceWidthForStopIndicator = MathUtils.ceilDiv(trackStopIndicatorSize, 2);

int newTrackSidePadding =
minTrackSidePadding
+ max(
max(increasedSidePaddingByThumb, increasedSidePaddingByTrack),
max(increasedSidePaddingByActiveTick, increasedSidePaddingByInactiveTick));
minTrackSidePadding +
MathUtils.max(
minSideSpaceWidthForThumb,
minSideSpaceWidthForTrack,
minSideSpaceWidthForActiveTick,
minSideSpaceWidthForInactiveTick,
minSideSpaceWidthForStopIndicator);

if (trackSidePadding == newTrackSidePadding) {
return false;
Expand Down Expand Up @@ -1589,8 +1595,8 @@ public void setTickInactiveRadius(@IntRange(from = 0) @Px int tickInactiveRadius
}

private void updateWidgetLayout(boolean forceRefresh) {
boolean sizeChanged = maybeIncreaseWidgetThickness();
boolean sidePaddingChanged = maybeIncreaseTrackSidePadding();
boolean sizeChanged = isWidgetThicknessChanged();
boolean sidePaddingChanged = isSidePaddingChanged();
if (isVertical()) {
updateRotationMatrix();
}
Expand All @@ -1601,22 +1607,33 @@ private void updateWidgetLayout(boolean forceRefresh) {
}
}

private boolean maybeIncreaseWidgetThickness() {
private boolean isWidgetThicknessChanged() {
int paddings;
if (isVertical()) {
paddings = getPaddingLeft() + getPaddingRight();
} else {
paddings = getPaddingTop() + getPaddingBottom();
}
int minHeightRequiredByTrack = trackThickness + paddings;
int minHeightRequiredByThumb = thumbHeight + paddings;

int newWidgetHeight =
max(minWidgetThickness, max(minHeightRequiredByTrack, minHeightRequiredByThumb));
if (newWidgetHeight == widgetThickness) {
int minSpaceHeightForThumb = thumbHeight;
int minSpaceHeightForTrack = trackThickness;
int minSpaceHeightForActiveTick = tickActiveRadius * 2;
int minSpaceHeightForInactiveTick = tickInactiveRadius * 2;
int minSpaceHeightForStopIndicator = trackStopIndicatorSize;

int newWidgetThickness = paddings +
MathUtils.max(
minSpaceHeightForThumb,
minSpaceHeightForTrack,
minSpaceHeightForActiveTick,
minSpaceHeightForInactiveTick,
minSpaceHeightForStopIndicator);

newWidgetThickness = max(minWidgetThickness, newWidgetThickness);
if (newWidgetThickness == widgetThickness) {
return false;
}
widgetThickness = newWidgetHeight;
widgetThickness = newWidgetThickness;
return true;
}

Expand Down