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 #3660
Resolves #2869
Resolves #3665

PiperOrigin-RevId: 581318308
  • Loading branch information
paulfthomas authored and dsn5ft committed Nov 13, 2023
1 parent 4246672 commit 5e5eee0
Showing 1 changed file with 27 additions and 4 deletions.
31 changes: 27 additions & 4 deletions lib/java/com/google/android/material/slider/BaseSlider.java
Expand Up @@ -57,6 +57,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import androidx.appcompat.content.res.AppCompatResources;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
Expand All @@ -65,6 +66,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 +340,22 @@ 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 (TooltipDrawable label : labels) {
positionLabel(label);
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 +1883,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 +1904,7 @@ protected void onDetachedFromWindow() {
for (TooltipDrawable label : labels) {
detachLabelFromContentView(label);
}

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

Expand Down Expand Up @@ -2646,10 +2665,16 @@ private String formatValue(float value) {

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

private void positionLabel(TooltipDrawable label) {
float labelValue = !TextUtils.isEmpty(label.getText())
? Float.parseFloat(label.getText().toString()) : 0;
int left =
trackSidePadding
+ (int) (normalizeValue(value) * trackWidth)
+ (int) (normalizeValue(labelValue) * trackWidth)
- label.getIntrinsicWidth() / 2;
int top = calculateTrackCenter() - (labelPadding + thumbHeight / 2);
label.setBounds(left, top - label.getIntrinsicHeight(), left + label.getIntrinsicWidth(), top);
Expand All @@ -2659,8 +2684,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 5e5eee0

Please sign in to comment.