25
25
import static com .google .android .material .slider .LabelFormatter .LABEL_GONE ;
26
26
import static com .google .android .material .slider .LabelFormatter .LABEL_VISIBLE ;
27
27
import static com .google .android .material .slider .LabelFormatter .LABEL_WITHIN_BOUNDS ;
28
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_AUTO_HIDE ;
29
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_AUTO_LIMIT ;
30
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_HIDDEN ;
31
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_VISIBLE_ALL ;
28
32
import static com .google .android .material .theme .overlay .MaterialThemeOverlay .wrap ;
29
33
import static java .lang .Float .compare ;
30
34
import static java .lang .Math .abs ;
149
153
* discrete mode. This is a short hand for setting both the {@code tickColorActive} and {@code
150
154
* tickColorInactive} to the same thing. This takes precedence over {@code tickColorActive}
151
155
* and {@code tickColorInactive}.
152
- * <li>{@code tickVisible}: Whether to show the tick marks. Only used when the slider is in
153
- * discrete mode.
156
+ * <li>{@code tickVisible} (deprecated, use {@code tickVisibilityMode} instead): Whether to show
157
+ * the tick marks. Only used when the slider is in discrete mode.
158
+ * <li>{@code tickVisibilityMode}: Mode to specify the visibility of tick marks. Only used when
159
+ * the slider is in discrete mode.
154
160
* <li>{@code trackColorActive}: The color of the active part of the track.
155
161
* <li>{@code trackColorInactive}: The color of the inactive part of the track.
156
162
* <li>{@code trackColor}: The color of the whole track. This is a short hand for setting both the
200
206
* @attr ref com.google.android.material.R.styleable#Slider_tickColorActive
201
207
* @attr ref com.google.android.material.R.styleable#Slider_tickColorInactive
202
208
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
209
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
203
210
* @attr ref com.google.android.material.R.styleable#Slider_trackColor
204
211
* @attr ref com.google.android.material.R.styleable#Slider_trackColorActive
205
212
* @attr ref com.google.android.material.R.styleable#Slider_trackColorInactive
@@ -317,7 +324,7 @@ abstract class BaseSlider<
317
324
private int focusedThumbIdx = -1 ;
318
325
private float stepSize = 0.0f ;
319
326
private float [] ticksCoordinates ;
320
- private boolean tickVisible = true ;
327
+ private int tickVisibilityMode ;
321
328
private int tickActiveRadius ;
322
329
private int tickInactiveRadius ;
323
330
private int trackWidth ;
@@ -513,7 +520,10 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
513
520
? haloColor
514
521
: AppCompatResources .getColorStateList (context , R .color .material_slider_halo_color ));
515
522
516
- tickVisible = a .getBoolean (R .styleable .Slider_tickVisible , true );
523
+ tickVisibilityMode = a .hasValue (R .styleable .Slider_tickVisibilityMode )
524
+ ? a .getInt (R .styleable .Slider_tickVisibilityMode , -1 )
525
+ : convertToTickVisibilityMode (a .getBoolean (R .styleable .Slider_tickVisible , true ));
526
+
517
527
boolean hasTickColor = a .hasValue (R .styleable .Slider_tickColor );
518
528
int tickColorInactiveRes =
519
529
hasTickColor ? R .styleable .Slider_tickColor : R .styleable .Slider_tickColorInactive ;
@@ -1676,22 +1686,61 @@ public void setTickInactiveTintList(@NonNull ColorStateList tickColor) {
1676
1686
/**
1677
1687
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
1678
1688
*
1679
- * @see #setTickVisible(boolean)
1680
1689
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1681
1690
*/
1682
1691
public boolean isTickVisible () {
1683
- return tickVisible ;
1692
+ switch (tickVisibilityMode ) {
1693
+ case TICK_VISIBILITY_VISIBLE_ALL :
1694
+ case TICK_VISIBILITY_AUTO_LIMIT :
1695
+ return true ;
1696
+ case TICK_VISIBILITY_AUTO_HIDE :
1697
+ return getDesiredTickCount () <= getMaxTickCount ();
1698
+ case TICK_VISIBILITY_HIDDEN :
1699
+ return false ;
1700
+ default :
1701
+ throw new RuntimeException ("isTickVisible() is not implemented for tickVisibilityMode=" + tickVisibilityMode );
1702
+ }
1684
1703
}
1685
1704
1686
1705
/**
1687
1706
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
1688
1707
*
1689
1708
* @param tickVisible The visibility of tick marks.
1690
1709
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1710
+ * @deprecated Use {@link #setTickVisibilityMode(int)} instead.
1691
1711
*/
1712
+ @ Deprecated
1692
1713
public void setTickVisible (boolean tickVisible ) {
1693
- if (this .tickVisible != tickVisible ) {
1694
- this .tickVisible = tickVisible ;
1714
+ setTickVisibilityMode (convertToTickVisibilityMode (tickVisible ));
1715
+ }
1716
+
1717
+ @ TickVisibilityMode
1718
+ private int convertToTickVisibilityMode (boolean tickVisible ) {
1719
+ return tickVisible
1720
+ ? TICK_VISIBILITY_AUTO_LIMIT
1721
+ : TICK_VISIBILITY_HIDDEN ;
1722
+ }
1723
+
1724
+ /**
1725
+ * Returns the current tick visibility mode.
1726
+ *
1727
+ * @see #setTickVisibilityMode(int)
1728
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1729
+ */
1730
+ @ TickVisibilityMode
1731
+ public int getTickVisibilityMode () {
1732
+ return tickVisibilityMode ;
1733
+ }
1734
+
1735
+ /**
1736
+ * Sets the tick visibility mode. Only used when the slider is in discrete mode.
1737
+ *
1738
+ * @see #getTickVisibilityMode()
1739
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1740
+ */
1741
+ public void setTickVisibilityMode (@ TickVisibilityMode int tickVisibilityMode ) {
1742
+ if (this .tickVisibilityMode != tickVisibilityMode ) {
1743
+ this .tickVisibilityMode = tickVisibilityMode ;
1695
1744
postInvalidate ();
1696
1745
}
1697
1746
}
@@ -1941,24 +1990,60 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
1941
1990
updateHaloHotspot ();
1942
1991
}
1943
1992
1944
- private void maybeCalculateTicksCoordinates () {
1993
+ private void updateTicksCoordinates () {
1994
+ validateConfigurationIfDirty ();
1995
+
1945
1996
if (stepSize <= 0.0f ) {
1997
+ updateTicksCoordinates (/* tickCount= */ 0 );
1946
1998
return ;
1947
1999
}
1948
2000
1949
- validateConfigurationIfDirty ();
2001
+ final int tickCount ;
2002
+ switch (tickVisibilityMode ) {
2003
+ case TICK_VISIBILITY_VISIBLE_ALL :
2004
+ tickCount = getDesiredTickCount ();
2005
+ break ;
2006
+ case TICK_VISIBILITY_AUTO_LIMIT :
2007
+ tickCount = min (getDesiredTickCount (), getMaxTickCount ());
2008
+ break ;
2009
+ case TICK_VISIBILITY_AUTO_HIDE :
2010
+ int desiredTickCount = getDesiredTickCount ();
2011
+ tickCount = desiredTickCount <= getMaxTickCount () ? desiredTickCount : 0 ;
2012
+ break ;
2013
+ case TICK_VISIBILITY_HIDDEN :
2014
+ tickCount = 0 ;
2015
+ break ;
2016
+ default :
2017
+ throw new RuntimeException ("Calculation of tick coordinates is not implemented for tickVisibilityMode=" + tickVisibilityMode );
2018
+ }
2019
+
2020
+ updateTicksCoordinates (tickCount );
2021
+ }
2022
+
2023
+ private int getDesiredTickCount () {
2024
+ return (int ) ((valueTo - valueFrom ) / stepSize + 1 );
2025
+ }
2026
+
2027
+ private int getMaxTickCount () {
2028
+ return trackWidth / minTickSpacing + 1 ;
2029
+ }
2030
+
2031
+ private void updateTicksCoordinates (int tickCount ) {
2032
+ if (tickCount == 0 ) {
2033
+ ticksCoordinates = null ;
2034
+ return ;
2035
+ }
1950
2036
1951
- int tickCount = (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1952
- // Limit the tickCount if they will be too dense.
1953
- tickCount = min (tickCount , trackWidth / minTickSpacing + 1 );
1954
2037
if (ticksCoordinates == null || ticksCoordinates .length != tickCount * 2 ) {
1955
2038
ticksCoordinates = new float [tickCount * 2 ];
1956
2039
}
1957
2040
1958
2041
float interval = trackWidth / (float ) (tickCount - 1 );
2042
+ float trackCenterY = calculateTrackCenter ();
2043
+
1959
2044
for (int i = 0 ; i < tickCount * 2 ; i += 2 ) {
1960
2045
ticksCoordinates [i ] = trackSidePadding + i / 2f * interval ;
1961
- ticksCoordinates [i + 1 ] = calculateTrackCenter () ;
2046
+ ticksCoordinates [i + 1 ] = trackCenterY ;
1962
2047
}
1963
2048
}
1964
2049
@@ -1967,7 +2052,7 @@ private void updateTrackWidth(int width) {
1967
2052
trackWidth = max (width - trackSidePadding * 2 , 0 );
1968
2053
1969
2054
// Update the visible tick coordinates.
1970
- maybeCalculateTicksCoordinates ();
2055
+ updateTicksCoordinates ();
1971
2056
}
1972
2057
1973
2058
private void updateHaloHotspot () {
@@ -1996,7 +2081,7 @@ protected void onDraw(@NonNull Canvas canvas) {
1996
2081
validateConfigurationIfDirty ();
1997
2082
1998
2083
// Update the visible tick coordinates.
1999
- maybeCalculateTicksCoordinates ();
2084
+ updateTicksCoordinates ();
2000
2085
}
2001
2086
2002
2087
super .onDraw (canvas );
@@ -2210,7 +2295,7 @@ private void drawRoundedCorners(
2210
2295
}
2211
2296
2212
2297
private void maybeDrawTicks (@ NonNull Canvas canvas ) {
2213
- if (! tickVisible || stepSize <= 0.0f ) {
2298
+ if (ticksCoordinates == null || ticksCoordinates . length == 0 ) {
2214
2299
return ;
2215
2300
}
2216
2301
0 commit comments