From ddda777dda853d55f7c4bd52d6f879b07a7c8882 Mon Sep 17 00:00:00 2001 From: pubiqq Date: Mon, 6 Jan 2025 22:26:00 +0000 Subject: [PATCH] [Slider] Always update track bounds before drawing icons Resolves https://github.com/material-components/material-components-android/pull/4488 GIT_ORIGIN_REV_ID=0437dc5fd010715429822287ec12a8f77bffbe92 PiperOrigin-RevId: 712658525 --- .../android/material/slider/BaseSlider.java | 75 ++++++++++++------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/lib/java/com/google/android/material/slider/BaseSlider.java b/lib/java/com/google/android/material/slider/BaseSlider.java index 6212302bca6..5bddbf4e504 100644 --- a/lib/java/com/google/android/material/slider/BaseSlider.java +++ b/lib/java/com/google/android/material/slider/BaseSlider.java @@ -368,7 +368,8 @@ abstract class BaseSlider< @NonNull private final Path trackPath = new Path(); @NonNull private final RectF activeTrackRect = new RectF(); - @NonNull private final RectF inactiveTrackRect = new RectF(); + @NonNull private final RectF inactiveTrackLeftRect = new RectF(); + @NonNull private final RectF inactiveTrackRightRect = new RectF(); @NonNull private final RectF cornerRect = new RectF(); @NonNull private final Rect labelRect = new Rect(); @NonNull private final RectF iconRectF = new RectF(); @@ -2410,15 +2411,14 @@ protected void onDraw(@NonNull Canvas canvas) { int yCenter = calculateTrackCenter(); - float first = values.get(0); - float last = values.get(values.size() - 1); - if (last < valueTo || (values.size() > 1 && first > valueFrom)) { - drawInactiveTrack(canvas, trackWidth, yCenter); - } - if (last > valueFrom) { - drawActiveTrack(canvas, trackWidth, yCenter); + drawInactiveTracks(canvas, trackWidth, yCenter); + drawActiveTracks(canvas, trackWidth, yCenter); + + if (isRtl() || isVertical()) { + drawTrackIcons(canvas, activeTrackRect, inactiveTrackLeftRect); + } else { + drawTrackIcons(canvas, activeTrackRect, inactiveTrackRightRect); } - drawTrackIcons(canvas, activeTrackRect, inactiveTrackRect); maybeDrawTicks(canvas); maybeDrawStopIndicator(canvas, yCenter); @@ -2446,34 +2446,50 @@ private float[] getActiveRange() { return isRtl() || isVertical() ? new float[] {right, left} : new float[] {left, right}; } - private void drawInactiveTrack(@NonNull Canvas canvas, int width, int yCenter) { - int trackCornerSize = getTrackCornerSize(); + private void drawInactiveTracks(@NonNull Canvas canvas, int width, int yCenter) { + populateInactiveTrackRightRect(width, yCenter); + updateTrack( + canvas, + inactiveTrackPaint, + inactiveTrackRightRect, + getTrackCornerSize(), + FullCornerDirection.RIGHT); + + // Also draw inactive track to the left if there is any + populateInactiveTrackLeftRect(width, yCenter); + updateTrack( + canvas, + inactiveTrackPaint, + inactiveTrackLeftRect, + getTrackCornerSize(), + FullCornerDirection.LEFT); + } + + private void populateInactiveTrackRightRect(int width, int yCenter) { float[] activeRange = getActiveRange(); float right = trackSidePadding + activeRange[1] * width; if (right < trackSidePadding + width) { - inactiveTrackRect.set( + inactiveTrackRightRect.set( right + thumbTrackGapSize, yCenter - trackThickness / 2f, - trackSidePadding + width + trackCornerSize, + trackSidePadding + width + getTrackCornerSize(), yCenter + trackThickness / 2f); - updateTrack( - canvas, - inactiveTrackPaint, - inactiveTrackRect, - trackCornerSize, - FullCornerDirection.RIGHT); + } else { + inactiveTrackRightRect.setEmpty(); } + } - // Also draw inactive track to the left if there is any + private void populateInactiveTrackLeftRect(int width, int yCenter) { + float[] activeRange = getActiveRange(); float left = trackSidePadding + activeRange[0] * width; if (left > trackSidePadding) { - inactiveTrackRect.set( - trackSidePadding - trackCornerSize, + inactiveTrackLeftRect.set( + trackSidePadding - getTrackCornerSize(), yCenter - trackThickness / 2f, left - thumbTrackGapSize, yCenter + trackThickness / 2f); - updateTrack( - canvas, inactiveTrackPaint, inactiveTrackRect, trackCornerSize, FullCornerDirection.LEFT); + } else { + inactiveTrackLeftRect.setEmpty(); } } @@ -2489,10 +2505,14 @@ private float normalizeValue(float value) { return normalized; } - private void drawActiveTrack(@NonNull Canvas canvas, int width, int yCenter) { + private void drawActiveTracks(@NonNull Canvas canvas, int width, int yCenter) { float[] activeRange = getActiveRange(); float right = trackSidePadding + activeRange[1] * width; float left = trackSidePadding + activeRange[0] * width; + if (left >= right) { + activeTrackRect.setEmpty(); + return; + } FullCornerDirection direction = FullCornerDirection.NONE; if (values.size() == 1) { // Only 1 thumb @@ -2532,6 +2552,7 @@ private void drawActiveTrack(@NonNull Canvas canvas, int width, int yCenter) { // Nothing to draw if left is bigger than right. if (left >= right) { + activeTrackRect.setEmpty(); continue; } @@ -2652,6 +2673,10 @@ private enum FullCornerDirection { private void updateTrack( Canvas canvas, Paint paint, RectF bounds, float cornerSize, FullCornerDirection direction) { + if (bounds.isEmpty()) { + return; + } + float leftCornerSize = calculateStartTrackCornerSize(cornerSize); float rightCornerSize = calculateEndTrackCornerSize(cornerSize); switch (direction) {