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 ;
@@ -501,7 +508,10 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
501
508
? haloColor
502
509
: AppCompatResources .getColorStateList (context , R .color .material_slider_halo_color ));
503
510
504
- tickVisible = a .getBoolean (R .styleable .Slider_tickVisible , true );
511
+ tickVisibilityMode = a .hasValue (R .styleable .Slider_tickVisibilityMode )
512
+ ? a .getInt (R .styleable .Slider_tickVisibilityMode , -1 )
513
+ : convertToTickVisibilityMode (a .getBoolean (R .styleable .Slider_tickVisible , true ));
514
+
505
515
boolean hasTickColor = a .hasValue (R .styleable .Slider_tickColor );
506
516
int tickColorInactiveRes =
507
517
hasTickColor ? R .styleable .Slider_tickColor : R .styleable .Slider_tickColorInactive ;
@@ -1669,22 +1679,61 @@ public void setTickInactiveTintList(@NonNull ColorStateList tickColor) {
1669
1679
/**
1670
1680
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
1671
1681
*
1672
- * @see #setTickVisible(boolean)
1673
1682
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1674
1683
*/
1675
1684
public boolean isTickVisible () {
1676
- return tickVisible ;
1685
+ switch (tickVisibilityMode ) {
1686
+ case TICK_VISIBILITY_VISIBLE_ALL :
1687
+ case TICK_VISIBILITY_AUTO_LIMIT :
1688
+ return true ;
1689
+ case TICK_VISIBILITY_AUTO_HIDE :
1690
+ return getDesiredTickCount () <= getMaxTickCount ();
1691
+ case TICK_VISIBILITY_HIDDEN :
1692
+ return false ;
1693
+ default :
1694
+ throw new RuntimeException ("Unexpected tickVisibilityMode: " + tickVisibilityMode );
1695
+ }
1677
1696
}
1678
1697
1679
1698
/**
1680
1699
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
1681
1700
*
1682
1701
* @param tickVisible The visibility of tick marks.
1683
1702
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1703
+ * @deprecated Use {@link #setTickVisibilityMode(int)} instead.
1684
1704
*/
1705
+ @ Deprecated
1685
1706
public void setTickVisible (boolean tickVisible ) {
1686
- if (this .tickVisible != tickVisible ) {
1687
- this .tickVisible = tickVisible ;
1707
+ setTickVisibilityMode (convertToTickVisibilityMode (tickVisible ));
1708
+ }
1709
+
1710
+ @ TickVisibilityMode
1711
+ private int convertToTickVisibilityMode (boolean tickVisible ) {
1712
+ return tickVisible
1713
+ ? TICK_VISIBILITY_AUTO_LIMIT
1714
+ : TICK_VISIBILITY_HIDDEN ;
1715
+ }
1716
+
1717
+ /**
1718
+ * Returns the current tick visibility mode.
1719
+ *
1720
+ * @see #setTickVisibilityMode(int)
1721
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1722
+ */
1723
+ @ TickVisibilityMode
1724
+ public int getTickVisibilityMode () {
1725
+ return tickVisibilityMode ;
1726
+ }
1727
+
1728
+ /**
1729
+ * Sets the tick visibility mode. Only used when the slider is in discrete mode.
1730
+ *
1731
+ * @see #getTickVisibilityMode()
1732
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1733
+ */
1734
+ public void setTickVisibilityMode (@ TickVisibilityMode int tickVisibilityMode ) {
1735
+ if (this .tickVisibilityMode != tickVisibilityMode ) {
1736
+ this .tickVisibilityMode = tickVisibilityMode ;
1688
1737
postInvalidate ();
1689
1738
}
1690
1739
}
@@ -1934,24 +1983,60 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
1934
1983
updateHaloHotspot ();
1935
1984
}
1936
1985
1937
- private void maybeCalculateTicksCoordinates () {
1986
+ private void updateTicksCoordinates () {
1987
+ validateConfigurationIfDirty ();
1988
+
1938
1989
if (stepSize <= 0.0f ) {
1990
+ updateTicksCoordinates (/* tickCount= */ 0 );
1939
1991
return ;
1940
1992
}
1941
1993
1942
- validateConfigurationIfDirty ();
1994
+ final int tickCount ;
1995
+ switch (tickVisibilityMode ) {
1996
+ case TICK_VISIBILITY_VISIBLE_ALL :
1997
+ tickCount = getDesiredTickCount ();
1998
+ break ;
1999
+ case TICK_VISIBILITY_AUTO_LIMIT :
2000
+ tickCount = min (getDesiredTickCount (), getMaxTickCount ());
2001
+ break ;
2002
+ case TICK_VISIBILITY_AUTO_HIDE :
2003
+ int desiredTickCount = getDesiredTickCount ();
2004
+ tickCount = desiredTickCount <= getMaxTickCount () ? desiredTickCount : 0 ;
2005
+ break ;
2006
+ case TICK_VISIBILITY_HIDDEN :
2007
+ tickCount = 0 ;
2008
+ break ;
2009
+ default :
2010
+ throw new RuntimeException ("Unexpected tickVisibilityMode: " + tickVisibilityMode );
2011
+ }
2012
+
2013
+ updateTicksCoordinates (tickCount );
2014
+ }
2015
+
2016
+ private int getDesiredTickCount () {
2017
+ return (int ) ((valueTo - valueFrom ) / stepSize + 1 );
2018
+ }
2019
+
2020
+ private int getMaxTickCount () {
2021
+ return trackWidth / minTickSpacing + 1 ;
2022
+ }
2023
+
2024
+ private void updateTicksCoordinates (int tickCount ) {
2025
+ if (tickCount == 0 ) {
2026
+ ticksCoordinates = null ;
2027
+ return ;
2028
+ }
1943
2029
1944
- int tickCount = (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1945
- // Limit the tickCount if they will be too dense.
1946
- tickCount = min (tickCount , trackWidth / minTickSpacing + 1 );
1947
2030
if (ticksCoordinates == null || ticksCoordinates .length != tickCount * 2 ) {
1948
2031
ticksCoordinates = new float [tickCount * 2 ];
1949
2032
}
1950
2033
1951
2034
float interval = trackWidth / (float ) (tickCount - 1 );
2035
+ float trackCenterY = calculateTrackCenter ();
2036
+
1952
2037
for (int i = 0 ; i < tickCount * 2 ; i += 2 ) {
1953
2038
ticksCoordinates [i ] = trackSidePadding + i / 2f * interval ;
1954
- ticksCoordinates [i + 1 ] = calculateTrackCenter () ;
2039
+ ticksCoordinates [i + 1 ] = trackCenterY ;
1955
2040
}
1956
2041
}
1957
2042
@@ -1960,7 +2045,7 @@ private void updateTrackWidth(int width) {
1960
2045
trackWidth = max (width - trackSidePadding * 2 , 0 );
1961
2046
1962
2047
// Update the visible tick coordinates.
1963
- maybeCalculateTicksCoordinates ();
2048
+ updateTicksCoordinates ();
1964
2049
}
1965
2050
1966
2051
private void updateHaloHotspot () {
@@ -1989,7 +2074,7 @@ protected void onDraw(@NonNull Canvas canvas) {
1989
2074
validateConfigurationIfDirty ();
1990
2075
1991
2076
// Update the visible tick coordinates.
1992
- maybeCalculateTicksCoordinates ();
2077
+ updateTicksCoordinates ();
1993
2078
}
1994
2079
1995
2080
super .onDraw (canvas );
@@ -2214,7 +2299,7 @@ private float[] getCornerRadii(float leftSide, float rightSide) {
2214
2299
}
2215
2300
2216
2301
private void maybeDrawTicks (@ NonNull Canvas canvas ) {
2217
- if (! tickVisible || stepSize <= 0.0f ) {
2302
+ if (ticksCoordinates == null || ticksCoordinates . length == 0 ) {
2218
2303
return ;
2219
2304
}
2220
2305
0 commit comments