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 ;
151
155
* discrete mode. This is a short hand for setting both the {@code tickColorActive} and {@code
152
156
* tickColorInactive} to the same thing. This takes precedence over {@code tickColorActive}
153
157
* and {@code tickColorInactive}.
154
- * <li>{@code tickVisible}: Whether to show the tick marks. Only used when the slider is in
155
- * discrete mode.
158
+ * <li>{@code tickVisible} (deprecated, use {@code tickVisibilityMode} instead): Whether to show
159
+ * the tick marks. Only used when the slider is in discrete mode.
160
+ * <li>{@code tickVisibilityMode}: Mode to specify the visibility of tick marks. Only used when
161
+ * the slider is in discrete mode.
156
162
* <li>{@code trackColorActive}: The color of the active part of the track.
157
163
* <li>{@code trackColorInactive}: The color of the inactive part of the track.
158
164
* <li>{@code trackColor}: The color of the whole track. This is a short hand for setting both the
202
208
* @attr ref com.google.android.material.R.styleable#Slider_tickColorActive
203
209
* @attr ref com.google.android.material.R.styleable#Slider_tickColorInactive
204
210
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
211
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
205
212
* @attr ref com.google.android.material.R.styleable#Slider_trackColor
206
213
* @attr ref com.google.android.material.R.styleable#Slider_trackColorActive
207
214
* @attr ref com.google.android.material.R.styleable#Slider_trackColorInactive
@@ -322,7 +329,7 @@ abstract class BaseSlider<
322
329
private int focusedThumbIdx = -1 ;
323
330
private float stepSize = 0.0f ;
324
331
private float [] ticksCoordinates ;
325
- private boolean tickVisible = true ;
332
+ private int tickVisibilityMode ;
326
333
private int tickActiveRadius ;
327
334
private int tickInactiveRadius ;
328
335
private int trackWidth ;
@@ -519,7 +526,10 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
519
526
? haloColor
520
527
: AppCompatResources .getColorStateList (context , R .color .material_slider_halo_color ));
521
528
522
- tickVisible = a .getBoolean (R .styleable .Slider_tickVisible , true );
529
+ tickVisibilityMode = a .hasValue (R .styleable .Slider_tickVisibilityMode )
530
+ ? a .getInt (R .styleable .Slider_tickVisibilityMode , -1 )
531
+ : convertToTickVisibilityMode (a .getBoolean (R .styleable .Slider_tickVisible , true ));
532
+
523
533
boolean hasTickColor = a .hasValue (R .styleable .Slider_tickColor );
524
534
int tickColorInactiveRes =
525
535
hasTickColor ? R .styleable .Slider_tickColor : R .styleable .Slider_tickColorInactive ;
@@ -1682,22 +1692,61 @@ public void setTickInactiveTintList(@NonNull ColorStateList tickColor) {
1682
1692
/**
1683
1693
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
1684
1694
*
1685
- * @see #setTickVisible(boolean)
1686
1695
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1687
1696
*/
1688
1697
public boolean isTickVisible () {
1689
- return tickVisible ;
1698
+ switch (tickVisibilityMode ) {
1699
+ case TICK_VISIBILITY_VISIBLE_ALL :
1700
+ case TICK_VISIBILITY_AUTO_LIMIT :
1701
+ return true ;
1702
+ case TICK_VISIBILITY_AUTO_HIDE :
1703
+ return getDesiredTickCount () <= getMaxTickCount ();
1704
+ case TICK_VISIBILITY_HIDDEN :
1705
+ return false ;
1706
+ default :
1707
+ throw new RuntimeException ("isTickVisible() is not implemented for tickVisibilityMode=" + tickVisibilityMode );
1708
+ }
1690
1709
}
1691
1710
1692
1711
/**
1693
1712
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
1694
1713
*
1695
1714
* @param tickVisible The visibility of tick marks.
1696
1715
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1716
+ * @deprecated Use {@link #setTickVisibilityMode(int)} instead.
1697
1717
*/
1718
+ @ Deprecated
1698
1719
public void setTickVisible (boolean tickVisible ) {
1699
- if (this .tickVisible != tickVisible ) {
1700
- this .tickVisible = tickVisible ;
1720
+ setTickVisibilityMode (convertToTickVisibilityMode (tickVisible ));
1721
+ }
1722
+
1723
+ @ TickVisibilityMode
1724
+ private int convertToTickVisibilityMode (boolean tickVisible ) {
1725
+ return tickVisible
1726
+ ? TICK_VISIBILITY_AUTO_LIMIT
1727
+ : TICK_VISIBILITY_HIDDEN ;
1728
+ }
1729
+
1730
+ /**
1731
+ * Returns the current tick visibility mode.
1732
+ *
1733
+ * @see #setTickVisibilityMode(int)
1734
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1735
+ */
1736
+ @ TickVisibilityMode
1737
+ public int getTickVisibilityMode () {
1738
+ return tickVisibilityMode ;
1739
+ }
1740
+
1741
+ /**
1742
+ * Sets the tick visibility mode. Only used when the slider is in discrete mode.
1743
+ *
1744
+ * @see #getTickVisibilityMode()
1745
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1746
+ */
1747
+ public void setTickVisibilityMode (@ TickVisibilityMode int tickVisibilityMode ) {
1748
+ if (this .tickVisibilityMode != tickVisibilityMode ) {
1749
+ this .tickVisibilityMode = tickVisibilityMode ;
1701
1750
postInvalidate ();
1702
1751
}
1703
1752
}
@@ -1947,24 +1996,60 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
1947
1996
updateHaloHotspot ();
1948
1997
}
1949
1998
1950
- private void maybeCalculateTicksCoordinates () {
1999
+ private void updateTicksCoordinates () {
2000
+ validateConfigurationIfDirty ();
2001
+
1951
2002
if (stepSize <= 0.0f ) {
2003
+ updateTicksCoordinates (/* tickCount= */ 0 );
1952
2004
return ;
1953
2005
}
1954
2006
1955
- validateConfigurationIfDirty ();
2007
+ final int tickCount ;
2008
+ switch (tickVisibilityMode ) {
2009
+ case TICK_VISIBILITY_VISIBLE_ALL :
2010
+ tickCount = getDesiredTickCount ();
2011
+ break ;
2012
+ case TICK_VISIBILITY_AUTO_LIMIT :
2013
+ tickCount = min (getDesiredTickCount (), getMaxTickCount ());
2014
+ break ;
2015
+ case TICK_VISIBILITY_AUTO_HIDE :
2016
+ int desiredTickCount = getDesiredTickCount ();
2017
+ tickCount = desiredTickCount <= getMaxTickCount () ? desiredTickCount : 0 ;
2018
+ break ;
2019
+ case TICK_VISIBILITY_HIDDEN :
2020
+ tickCount = 0 ;
2021
+ break ;
2022
+ default :
2023
+ throw new RuntimeException ("Calculation of tick coordinates is not implemented for tickVisibilityMode=" + tickVisibilityMode );
2024
+ }
2025
+
2026
+ updateTicksCoordinates (tickCount );
2027
+ }
2028
+
2029
+ private int getDesiredTickCount () {
2030
+ return (int ) ((valueTo - valueFrom ) / stepSize + 1 );
2031
+ }
2032
+
2033
+ private int getMaxTickCount () {
2034
+ return trackWidth / minTickSpacing + 1 ;
2035
+ }
2036
+
2037
+ private void updateTicksCoordinates (int tickCount ) {
2038
+ if (tickCount == 0 ) {
2039
+ ticksCoordinates = null ;
2040
+ return ;
2041
+ }
1956
2042
1957
- int tickCount = (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1958
- // Limit the tickCount if they will be too dense.
1959
- tickCount = min (tickCount , trackWidth / minTickSpacing + 1 );
1960
2043
if (ticksCoordinates == null || ticksCoordinates .length != tickCount * 2 ) {
1961
2044
ticksCoordinates = new float [tickCount * 2 ];
1962
2045
}
1963
2046
1964
2047
float interval = trackWidth / (float ) (tickCount - 1 );
2048
+ float trackCenterY = calculateTrackCenter ();
2049
+
1965
2050
for (int i = 0 ; i < tickCount * 2 ; i += 2 ) {
1966
2051
ticksCoordinates [i ] = trackSidePadding + i / 2f * interval ;
1967
- ticksCoordinates [i + 1 ] = calculateTrackCenter () ;
2052
+ ticksCoordinates [i + 1 ] = trackCenterY ;
1968
2053
}
1969
2054
}
1970
2055
@@ -1973,7 +2058,7 @@ private void updateTrackWidth(int width) {
1973
2058
trackWidth = max (width - trackSidePadding * 2 , 0 );
1974
2059
1975
2060
// Update the visible tick coordinates.
1976
- maybeCalculateTicksCoordinates ();
2061
+ updateTicksCoordinates ();
1977
2062
}
1978
2063
1979
2064
private void updateHaloHotspot () {
@@ -2002,7 +2087,7 @@ protected void onDraw(@NonNull Canvas canvas) {
2002
2087
validateConfigurationIfDirty ();
2003
2088
2004
2089
// Update the visible tick coordinates.
2005
- maybeCalculateTicksCoordinates ();
2090
+ updateTicksCoordinates ();
2006
2091
}
2007
2092
2008
2093
super .onDraw (canvas );
@@ -2213,7 +2298,7 @@ private void addRoundedCorners(
2213
2298
}
2214
2299
2215
2300
private void maybeDrawTicks (@ NonNull Canvas canvas ) {
2216
- if (! tickVisible || stepSize <= 0.0f ) {
2301
+ if (ticksCoordinates == null || ticksCoordinates . length == 0 ) {
2217
2302
return ;
2218
2303
}
2219
2304
0 commit comments