Skip to content

Commit dc0d8a9

Browse files
committed
[Slider] Make slider's height adjustable with track height or thumb radius
Resolves #1923 PiperOrigin-RevId: 440913851
1 parent e9b04a6 commit dc0d8a9

File tree

2 files changed

+60
-31
lines changed

2 files changed

+60
-31
lines changed

lib/java/com/google/android/material/slider/BaseSlider.java

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,13 @@ private interface TooltipDrawableFactory {
262262

263263
private int minTrackSidePadding;
264264
private int defaultThumbRadius;
265+
private int defaultTrackHeight;
265266

267+
private int minWidgetHeight;
266268
private int widgetHeight;
267269
private int labelBehavior;
268270
private int trackHeight;
269271
private int trackSidePadding;
270-
private int trackTop;
271272
private int thumbRadius;
272273
private int haloRadius;
273274
private int labelPadding;
@@ -400,14 +401,13 @@ public TooltipDrawable createTooltipDrawable() {
400401
}
401402

402403
private void loadResources(@NonNull Resources resources) {
403-
widgetHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_widget_height);
404+
minWidgetHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_widget_height);
404405

405406
minTrackSidePadding = resources.getDimensionPixelOffset(R.dimen.mtrl_slider_track_side_padding);
406407
trackSidePadding = minTrackSidePadding;
407408

408409
defaultThumbRadius = resources.getDimensionPixelSize(R.dimen.mtrl_slider_thumb_radius);
409-
410-
trackTop = resources.getDimensionPixelOffset(R.dimen.mtrl_slider_track_top);
410+
defaultTrackHeight = resources.getDimensionPixelSize(R.dimen.mtrl_slider_track_height);
411411

412412
labelPadding = resources.getDimensionPixelSize(R.dimen.mtrl_slider_label_padding);
413413
}
@@ -506,12 +506,19 @@ private static TooltipDrawable parseLabelDrawable(
506506
a.getResourceId(R.styleable.Slider_labelStyle, R.style.Widget_MaterialComponents_Tooltip));
507507
}
508508

509-
private void maybeIncreaseTrackSidePadding() {
510-
int increasedSidePadding = max(thumbRadius - defaultThumbRadius, 0);
511-
trackSidePadding = minTrackSidePadding + increasedSidePadding;
509+
private boolean maybeIncreaseTrackSidePadding() {
510+
int increasedSidePaddingByThumb = max(thumbRadius - defaultThumbRadius, 0);
511+
int increasedSidePaddingByTrack = max((trackHeight - defaultTrackHeight) / 2, 0);
512+
int newTrackSidePadding =
513+
minTrackSidePadding + max(increasedSidePaddingByThumb, increasedSidePaddingByTrack);
514+
if (trackSidePadding == newTrackSidePadding) {
515+
return false;
516+
}
517+
trackSidePadding = newTrackSidePadding;
512518
if (ViewCompat.isLaidOut(this)) {
513519
updateTrackWidth(getWidth());
514520
}
521+
return true;
515522
}
516523

517524
private void validateValueFrom() {
@@ -1050,7 +1057,6 @@ public void setThumbRadius(@IntRange(from = 0) @Dimension int radius) {
10501057
}
10511058

10521059
thumbRadius = radius;
1053-
maybeIncreaseTrackSidePadding();
10541060

10551061
defaultThumbDrawable.setShapeAppearanceModel(
10561062
ShapeAppearanceModel.builder().setAllCorners(CornerFamily.ROUNDED, thumbRadius).build());
@@ -1063,7 +1069,7 @@ public void setThumbRadius(@IntRange(from = 0) @Dimension int radius) {
10631069
adjustCustomThumbDrawableBounds(customDrawable);
10641070
}
10651071

1066-
postInvalidate();
1072+
updateWidgetLayout();
10671073
}
10681074

10691075
/**
@@ -1273,10 +1279,34 @@ public void setTrackHeight(@IntRange(from = 0) @Dimension int trackHeight) {
12731279
if (this.trackHeight != trackHeight) {
12741280
this.trackHeight = trackHeight;
12751281
invalidateTrack();
1282+
updateWidgetLayout();
1283+
}
1284+
}
1285+
1286+
private void updateWidgetLayout() {
1287+
boolean sizeChanged = maybeIncreaseWidgetHeight();
1288+
boolean sidePaddingChanged = maybeIncreaseTrackSidePadding();
1289+
if (sizeChanged) {
1290+
requestLayout();
1291+
} else if (sidePaddingChanged) {
12761292
postInvalidate();
12771293
}
12781294
}
12791295

1296+
private boolean maybeIncreaseWidgetHeight() {
1297+
int topAndBottomPaddings = getPaddingTop() + getPaddingBottom();
1298+
int minHeightRequiredByTrack = trackHeight + topAndBottomPaddings;
1299+
int minHeightRequiredByThumb = thumbRadius * 2 + getPaddingTop() + getPaddingBottom();
1300+
1301+
int newWidgetHeight =
1302+
max(minWidgetHeight, max(minHeightRequiredByTrack, minHeightRequiredByThumb));
1303+
if (newWidgetHeight == widgetHeight) {
1304+
return false;
1305+
}
1306+
widgetHeight = newWidgetHeight;
1307+
return true;
1308+
}
1309+
12801310
/**
12811311
* Returns the color of the halo.
12821312
*
@@ -1624,7 +1654,7 @@ private void maybeCalculateTicksCoordinates() {
16241654
float interval = trackWidth / (float) (tickCount - 1);
16251655
for (int i = 0; i < tickCount * 2; i += 2) {
16261656
ticksCoordinates[i] = trackSidePadding + i / 2 * interval;
1627-
ticksCoordinates[i + 1] = calculateTop();
1657+
ticksCoordinates[i + 1] = calculateTrackCenter();
16281658
}
16291659
}
16301660

@@ -1642,15 +1672,15 @@ private void updateHaloHotspot() {
16421672
final Drawable background = getBackground();
16431673
if (background instanceof RippleDrawable) {
16441674
int x = (int) (normalizeValue(values.get(focusedThumbIdx)) * trackWidth + trackSidePadding);
1645-
int y = calculateTop();
1675+
int y = calculateTrackCenter();
16461676
DrawableCompat.setHotspotBounds(
16471677
background, x - haloRadius, y - haloRadius, x + haloRadius, y + haloRadius);
16481678
}
16491679
}
16501680
}
16511681

1652-
private int calculateTop() {
1653-
return trackTop
1682+
private int calculateTrackCenter() {
1683+
return widgetHeight / 2
16541684
+ (labelBehavior == LABEL_WITHIN_BOUNDS || shouldAlwaysShowLabel()
16551685
? labels.get(0).getIntrinsicHeight()
16561686
: 0);
@@ -1667,17 +1697,17 @@ protected void onDraw(@NonNull Canvas canvas) {
16671697

16681698
super.onDraw(canvas);
16691699

1670-
int top = calculateTop();
1700+
int yCenter = calculateTrackCenter();
16711701

1672-
drawInactiveTrack(canvas, trackWidth, top);
1702+
drawInactiveTrack(canvas, trackWidth, yCenter);
16731703
if (max(getValues()) > valueFrom) {
1674-
drawActiveTrack(canvas, trackWidth, top);
1704+
drawActiveTrack(canvas, trackWidth, yCenter);
16751705
}
16761706

16771707
maybeDrawTicks(canvas);
16781708

16791709
if ((thumbIsPressed || isFocused() || shouldAlwaysShowLabel()) && isEnabled()) {
1680-
maybeDrawHalo(canvas, trackWidth, top);
1710+
maybeDrawHalo(canvas, trackWidth, yCenter);
16811711
// Draw labels if there is an active thumb or the labels are always visible.
16821712
if (activeThumbIdx != -1 || shouldAlwaysShowLabel()) {
16831713
ensureLabelsAdded();
@@ -1688,7 +1718,7 @@ protected void onDraw(@NonNull Canvas canvas) {
16881718
ensureLabelsRemoved();
16891719
}
16901720

1691-
drawThumbs(canvas, trackWidth, top);
1721+
drawThumbs(canvas, trackWidth, yCenter);
16921722
}
16931723

16941724
/**
@@ -1705,17 +1735,17 @@ private float[] getActiveRange() {
17051735
return isRtl() ? new float[] {right, left} : new float[] {left, right};
17061736
}
17071737

1708-
private void drawInactiveTrack(@NonNull Canvas canvas, int width, int top) {
1738+
private void drawInactiveTrack(@NonNull Canvas canvas, int width, int yCenter) {
17091739
float[] activeRange = getActiveRange();
17101740
float right = trackSidePadding + activeRange[1] * width;
17111741
if (right < trackSidePadding + width) {
1712-
canvas.drawLine(right, top, trackSidePadding + width, top, inactiveTrackPaint);
1742+
canvas.drawLine(right, yCenter, trackSidePadding + width, yCenter, inactiveTrackPaint);
17131743
}
17141744

17151745
// Also draw inactive track to the left if there is any
17161746
float left = trackSidePadding + activeRange[0] * width;
17171747
if (left > trackSidePadding) {
1718-
canvas.drawLine(trackSidePadding, top, left, top, inactiveTrackPaint);
1748+
canvas.drawLine(trackSidePadding, yCenter, left, yCenter, inactiveTrackPaint);
17191749
}
17201750
}
17211751

@@ -1731,11 +1761,11 @@ private float normalizeValue(float value) {
17311761
return normalized;
17321762
}
17331763

1734-
private void drawActiveTrack(@NonNull Canvas canvas, int width, int top) {
1764+
private void drawActiveTrack(@NonNull Canvas canvas, int width, int yCenter) {
17351765
float[] activeRange = getActiveRange();
17361766
float right = trackSidePadding + activeRange[1] * width;
17371767
float left = trackSidePadding + activeRange[0] * width;
1738-
canvas.drawLine(left, top, right, top, activeTrackPaint);
1768+
canvas.drawLine(left, yCenter, right, yCenter, activeTrackPaint);
17391769
}
17401770

17411771
private void maybeDrawTicks(@NonNull Canvas canvas) {
@@ -1765,21 +1795,21 @@ private void maybeDrawTicks(@NonNull Canvas canvas) {
17651795
inactiveTicksPaint);
17661796
}
17671797

1768-
private void drawThumbs(@NonNull Canvas canvas, int width, int top) {
1798+
private void drawThumbs(@NonNull Canvas canvas, int width, int yCenter) {
17691799
for (int i = 0; i < values.size(); i++) {
17701800
float value = values.get(i);
17711801
if (customThumbDrawable != null) {
1772-
drawThumbDrawable(canvas, width, top, value, customThumbDrawable);
1802+
drawThumbDrawable(canvas, width, yCenter, value, customThumbDrawable);
17731803
} else if (i < customThumbDrawablesForValues.size()) {
1774-
drawThumbDrawable(canvas, width, top, value, customThumbDrawablesForValues.get(i));
1804+
drawThumbDrawable(canvas, width, yCenter, value, customThumbDrawablesForValues.get(i));
17751805
} else {
17761806
// Clear out the track behind the thumb if we're in a disable state since the thumb is
17771807
// transparent.
17781808
if (!isEnabled()) {
17791809
canvas.drawCircle(
1780-
trackSidePadding + normalizeValue(value) * width, top, thumbRadius, thumbPaint);
1810+
trackSidePadding + normalizeValue(value) * width, yCenter, thumbRadius, thumbPaint);
17811811
}
1782-
drawThumbDrawable(canvas, width, top, value, defaultThumbDrawable);
1812+
drawThumbDrawable(canvas, width, yCenter, value, defaultThumbDrawable);
17831813
}
17841814
}
17851815
}
@@ -2178,7 +2208,7 @@ private void setValueForLabel(TooltipDrawable label, float value) {
21782208
trackSidePadding
21792209
+ (int) (normalizeValue(value) * trackWidth)
21802210
- label.getIntrinsicWidth() / 2;
2181-
int top = calculateTop() - (labelPadding + thumbRadius);
2211+
int top = calculateTrackCenter() - (labelPadding + thumbRadius);
21822212
label.setBounds(left, top - label.getIntrinsicHeight(), left + label.getIntrinsicWidth(), top);
21832213

21842214
// 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) {
26202650

26212651
void updateBoundsForVirturalViewId(int virtualViewId, Rect virtualViewBounds) {
26222652
int x = trackSidePadding + (int) (normalizeValue(getValues().get(virtualViewId)) * trackWidth);
2623-
int y = calculateTop();
2653+
int y = calculateTrackCenter();
26242654

26252655
virtualViewBounds.set(x - thumbRadius, y - thumbRadius, x + thumbRadius, y + thumbRadius);
26262656
}

lib/java/com/google/android/material/slider/res/values/dimens.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
<dimen name="mtrl_slider_widget_height">48dp</dimen>
2020

2121
<dimen name="mtrl_slider_track_side_padding">16dp</dimen>
22-
<dimen name="mtrl_slider_track_top">24dp</dimen>
2322
<dimen name="mtrl_slider_track_height">4dp</dimen>
2423

2524
<dimen name="mtrl_slider_thumb_radius">10dp</dimen>

0 commit comments

Comments
 (0)