diff --git a/lib/java/com/google/android/material/slider/BaseSlider.java b/lib/java/com/google/android/material/slider/BaseSlider.java
index ac793f6aa21..39b95480c66 100644
--- a/lib/java/com/google/android/material/slider/BaseSlider.java
+++ b/lib/java/com/google/android/material/slider/BaseSlider.java
@@ -262,12 +262,13 @@ private interface TooltipDrawableFactory {
private int minTrackSidePadding;
private int defaultThumbRadius;
+ private int defaultTrackHeight;
+ private int minWidgetHeight;
private int widgetHeight;
private int labelBehavior;
private int trackHeight;
private int trackSidePadding;
- private int trackTop;
private int thumbRadius;
private int haloRadius;
private int labelPadding;
@@ -400,14 +401,13 @@ public TooltipDrawable createTooltipDrawable() {
}
private void loadResources(@NonNull Resources resources) {
- widgetHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_widget_height);
+ minWidgetHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_widget_height);
minTrackSidePadding = resources.getDimensionPixelOffset(R.dimen.mtrl_slider_track_side_padding);
trackSidePadding = minTrackSidePadding;
defaultThumbRadius = resources.getDimensionPixelSize(R.dimen.mtrl_slider_thumb_radius);
-
- trackTop = resources.getDimensionPixelOffset(R.dimen.mtrl_slider_track_top);
+ defaultTrackHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_track_height);
labelPadding = resources.getDimensionPixelSize(R.dimen.mtrl_slider_label_padding);
}
@@ -506,12 +506,19 @@ private static TooltipDrawable parseLabelDrawable(
a.getResourceId(R.styleable.Slider_labelStyle, R.style.Widget_MaterialComponents_Tooltip));
}
- private void maybeIncreaseTrackSidePadding() {
- int increasedSidePadding = max(thumbRadius - defaultThumbRadius, 0);
- trackSidePadding = minTrackSidePadding + increasedSidePadding;
+ private boolean maybeIncreaseTrackSidePadding() {
+ int increasedSidePaddingByThumb = max(thumbRadius - defaultThumbRadius, 0);
+ int increasedSidePaddingByTrack = max((trackHeight - defaultTrackHeight) / 2, 0);
+ int newTrackSidePadding =
+ minTrackSidePadding + max(increasedSidePaddingByThumb, increasedSidePaddingByTrack);
+ if (trackSidePadding == newTrackSidePadding) {
+ return false;
+ }
+ trackSidePadding = newTrackSidePadding;
if (ViewCompat.isLaidOut(this)) {
updateTrackWidth(getWidth());
}
+ return true;
}
private void validateValueFrom() {
@@ -1050,7 +1057,6 @@ public void setThumbRadius(@IntRange(from = 0) @Dimension int radius) {
}
thumbRadius = radius;
- maybeIncreaseTrackSidePadding();
defaultThumbDrawable.setShapeAppearanceModel(
ShapeAppearanceModel.builder().setAllCorners(CornerFamily.ROUNDED, thumbRadius).build());
@@ -1063,7 +1069,7 @@ public void setThumbRadius(@IntRange(from = 0) @Dimension int radius) {
adjustCustomThumbDrawableBounds(customDrawable);
}
- postInvalidate();
+ updateWidgetLayout();
}
/**
@@ -1273,10 +1279,34 @@ public void setTrackHeight(@IntRange(from = 0) @Dimension int trackHeight) {
if (this.trackHeight != trackHeight) {
this.trackHeight = trackHeight;
invalidateTrack();
+ updateWidgetLayout();
+ }
+ }
+
+ private void updateWidgetLayout() {
+ boolean sizeChanged = maybeIncreaseWidgetHeight();
+ boolean sidePaddingChanged = maybeIncreaseTrackSidePadding();
+ if (sizeChanged) {
+ requestLayout();
+ } else if (sidePaddingChanged) {
postInvalidate();
}
}
+ private boolean maybeIncreaseWidgetHeight() {
+ int topAndBottomPaddings = getPaddingTop() + getPaddingBottom();
+ int minHeightRequiredByTrack = trackHeight + topAndBottomPaddings;
+ int minHeightRequiredByThumb = thumbRadius * 2 + getPaddingTop() + getPaddingBottom();
+
+ int newWidgetHeight =
+ max(minWidgetHeight, max(minHeightRequiredByTrack, minHeightRequiredByThumb));
+ if (newWidgetHeight == widgetHeight) {
+ return false;
+ }
+ widgetHeight = newWidgetHeight;
+ return true;
+ }
+
/**
* Returns the color of the halo.
*
@@ -1624,7 +1654,7 @@ private void maybeCalculateTicksCoordinates() {
float interval = trackWidth / (float) (tickCount - 1);
for (int i = 0; i < tickCount * 2; i += 2) {
ticksCoordinates[i] = trackSidePadding + i / 2 * interval;
- ticksCoordinates[i + 1] = calculateTop();
+ ticksCoordinates[i + 1] = calculateTrackCenter();
}
}
@@ -1642,15 +1672,15 @@ private void updateHaloHotspot() {
final Drawable background = getBackground();
if (background instanceof RippleDrawable) {
int x = (int) (normalizeValue(values.get(focusedThumbIdx)) * trackWidth + trackSidePadding);
- int y = calculateTop();
+ int y = calculateTrackCenter();
DrawableCompat.setHotspotBounds(
background, x - haloRadius, y - haloRadius, x + haloRadius, y + haloRadius);
}
}
}
- private int calculateTop() {
- return trackTop
+ private int calculateTrackCenter() {
+ return widgetHeight / 2
+ (labelBehavior == LABEL_WITHIN_BOUNDS || shouldAlwaysShowLabel()
? labels.get(0).getIntrinsicHeight()
: 0);
@@ -1667,17 +1697,17 @@ protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
- int top = calculateTop();
+ int yCenter = calculateTrackCenter();
- drawInactiveTrack(canvas, trackWidth, top);
+ drawInactiveTrack(canvas, trackWidth, yCenter);
if (max(getValues()) > valueFrom) {
- drawActiveTrack(canvas, trackWidth, top);
+ drawActiveTrack(canvas, trackWidth, yCenter);
}
maybeDrawTicks(canvas);
if ((thumbIsPressed || isFocused() || shouldAlwaysShowLabel()) && isEnabled()) {
- maybeDrawHalo(canvas, trackWidth, top);
+ maybeDrawHalo(canvas, trackWidth, yCenter);
// Draw labels if there is an active thumb or the labels are always visible.
if (activeThumbIdx != -1 || shouldAlwaysShowLabel()) {
ensureLabelsAdded();
@@ -1688,7 +1718,7 @@ protected void onDraw(@NonNull Canvas canvas) {
ensureLabelsRemoved();
}
- drawThumbs(canvas, trackWidth, top);
+ drawThumbs(canvas, trackWidth, yCenter);
}
/**
@@ -1705,17 +1735,17 @@ private float[] getActiveRange() {
return isRtl() ? new float[] {right, left} : new float[] {left, right};
}
- private void drawInactiveTrack(@NonNull Canvas canvas, int width, int top) {
+ private void drawInactiveTrack(@NonNull Canvas canvas, int width, int yCenter) {
float[] activeRange = getActiveRange();
float right = trackSidePadding + activeRange[1] * width;
if (right < trackSidePadding + width) {
- canvas.drawLine(right, top, trackSidePadding + width, top, inactiveTrackPaint);
+ canvas.drawLine(right, yCenter, trackSidePadding + width, yCenter, inactiveTrackPaint);
}
// Also draw inactive track to the left if there is any
float left = trackSidePadding + activeRange[0] * width;
if (left > trackSidePadding) {
- canvas.drawLine(trackSidePadding, top, left, top, inactiveTrackPaint);
+ canvas.drawLine(trackSidePadding, yCenter, left, yCenter, inactiveTrackPaint);
}
}
@@ -1731,11 +1761,11 @@ private float normalizeValue(float value) {
return normalized;
}
- private void drawActiveTrack(@NonNull Canvas canvas, int width, int top) {
+ private void drawActiveTrack(@NonNull Canvas canvas, int width, int yCenter) {
float[] activeRange = getActiveRange();
float right = trackSidePadding + activeRange[1] * width;
float left = trackSidePadding + activeRange[0] * width;
- canvas.drawLine(left, top, right, top, activeTrackPaint);
+ canvas.drawLine(left, yCenter, right, yCenter, activeTrackPaint);
}
private void maybeDrawTicks(@NonNull Canvas canvas) {
@@ -1765,21 +1795,21 @@ private void maybeDrawTicks(@NonNull Canvas canvas) {
inactiveTicksPaint);
}
- private void drawThumbs(@NonNull Canvas canvas, int width, int top) {
+ private void drawThumbs(@NonNull Canvas canvas, int width, int yCenter) {
for (int i = 0; i < values.size(); i++) {
float value = values.get(i);
if (customThumbDrawable != null) {
- drawThumbDrawable(canvas, width, top, value, customThumbDrawable);
+ drawThumbDrawable(canvas, width, yCenter, value, customThumbDrawable);
} else if (i < customThumbDrawablesForValues.size()) {
- drawThumbDrawable(canvas, width, top, value, customThumbDrawablesForValues.get(i));
+ drawThumbDrawable(canvas, width, yCenter, value, customThumbDrawablesForValues.get(i));
} else {
// Clear out the track behind the thumb if we're in a disable state since the thumb is
// transparent.
if (!isEnabled()) {
canvas.drawCircle(
- trackSidePadding + normalizeValue(value) * width, top, thumbRadius, thumbPaint);
+ trackSidePadding + normalizeValue(value) * width, yCenter, thumbRadius, thumbPaint);
}
- drawThumbDrawable(canvas, width, top, value, defaultThumbDrawable);
+ drawThumbDrawable(canvas, width, yCenter, value, defaultThumbDrawable);
}
}
}
@@ -2178,7 +2208,7 @@ private void setValueForLabel(TooltipDrawable label, float value) {
trackSidePadding
+ (int) (normalizeValue(value) * trackWidth)
- label.getIntrinsicWidth() / 2;
- int top = calculateTop() - (labelPadding + thumbRadius);
+ int top = calculateTrackCenter() - (labelPadding + thumbRadius);
label.setBounds(left, top - label.getIntrinsicHeight(), left + label.getIntrinsicWidth(), top);
// Calculate the difference between the bounds of this view and the bounds of the root view to
@@ -2620,7 +2650,7 @@ public void writeToParcel(@NonNull Parcel dest, int flags) {
void updateBoundsForVirturalViewId(int virtualViewId, Rect virtualViewBounds) {
int x = trackSidePadding + (int) (normalizeValue(getValues().get(virtualViewId)) * trackWidth);
- int y = calculateTop();
+ int y = calculateTrackCenter();
virtualViewBounds.set(x - thumbRadius, y - thumbRadius, x + thumbRadius, y + thumbRadius);
}
diff --git a/lib/java/com/google/android/material/slider/res/values/dimens.xml b/lib/java/com/google/android/material/slider/res/values/dimens.xml
index 8fb8df21441..74077e97acf 100644
--- a/lib/java/com/google/android/material/slider/res/values/dimens.xml
+++ b/lib/java/com/google/android/material/slider/res/values/dimens.xml
@@ -19,7 +19,6 @@
48dp
16dp
- 24dp
4dp
10dp