Skip to content

Commit

Permalink
[Slider] Fix slider label not moving while scrolling
Browse files Browse the repository at this point in the history
Resolves #3848
Resolves #3847

GIT_ORIGIN_REV_ID=630698384082464cfb40d75156ec09abfc829bed
PiperOrigin-RevId: 584067588
  • Loading branch information
manabu-nakamura authored and leticiarossi committed Nov 20, 2023
1 parent 54d2c8b commit 144b515
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions lib/java/com/google/android/material/slider/BaseSlider.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.SeekBar;
Expand Down Expand Up @@ -338,6 +339,26 @@ abstract class BaseSlider<
private float touchPosition;
@SeparationUnit private int separationUnit = UNIT_PX;

@NonNull private final ViewTreeObserver.OnScrollChangedListener onScrollChangedListener = () -> {
if (shouldAlwaysShowLabel() && isEnabled()) {
Rect contentViewBounds = new Rect();
ViewUtils.getContentView(this).getHitRect(contentViewBounds);
boolean isSliderVisibleOnScreen = getLocalVisibleRect(contentViewBounds);
for (int i = 0; i < labels.size(); i++) {
TooltipDrawable label = labels.get(i);
// Get associated value for label
if (i < values.size()) {
positionLabel(label, values.get(i));
}
if (isSliderVisibleOnScreen) {
ViewUtils.getContentViewOverlay(this).add(label);
} else {
ViewUtils.getContentViewOverlay(this).remove(label);
}
}
}
};

/**
* Determines the behavior of the label which can be any of the following.
*
Expand Down Expand Up @@ -1865,6 +1886,7 @@ public void setEnabled(boolean enabled) {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewTreeObserver().addOnScrollChangedListener(onScrollChangedListener);
// The label is attached on the Overlay relative to the content.
for (TooltipDrawable label : labels) {
attachLabelToContentView(label);
Expand All @@ -1885,7 +1907,7 @@ protected void onDetachedFromWindow() {
for (TooltipDrawable label : labels) {
detachLabelFromContentView(label);
}

getViewTreeObserver().removeOnScrollChangedListener(onScrollChangedListener);
super.onDetachedFromWindow();
}

Expand Down Expand Up @@ -2646,7 +2668,11 @@ private String formatValue(float value) {

private void setValueForLabel(TooltipDrawable label, float value) {
label.setText(formatValue(value));
positionLabel(label, value);
ViewUtils.getContentViewOverlay(this).add(label);
}

private void positionLabel(TooltipDrawable label, float value) {
int left =
trackSidePadding
+ (int) (normalizeValue(value) * trackWidth)
Expand All @@ -2659,8 +2685,6 @@ private void setValueForLabel(TooltipDrawable label, float value) {
Rect rect = new Rect(label.getBounds());
DescendantOffsetUtils.offsetDescendantRect(ViewUtils.getContentView(this), this, rect);
label.setBounds(rect);

ViewUtils.getContentViewOverlay(this).add(label);
}

private void invalidateTrack() {
Expand Down

0 comments on commit 144b515

Please sign in to comment.