29
29
import static com .google .android .material .slider .LabelFormatter .LABEL_WITHIN_BOUNDS ;
30
30
import static com .google .android .material .slider .SliderOrientation .HORIZONTAL ;
31
31
import static com .google .android .material .slider .SliderOrientation .VERTICAL ;
32
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_AUTO_HIDE ;
33
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_AUTO_LIMIT ;
34
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_HIDDEN ;
35
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_VISIBLE_ALL ;
32
36
import static com .google .android .material .theme .overlay .MaterialThemeOverlay .wrap ;
33
37
import static java .lang .Float .compare ;
34
38
import static java .lang .Math .abs ;
157
161
* discrete mode. This is a short hand for setting both the {@code tickColorActive} and {@code
158
162
* tickColorInactive} to the same thing. This takes precedence over {@code tickColorActive}
159
163
* and {@code tickColorInactive}.
160
- * <li>{@code tickVisible}: Whether to show the tick marks. Only used when the slider is in
161
- * discrete mode.
164
+ * <li>{@code tickVisible} (<b>deprecated</b>, use {@code tickVisibilityMode} instead):
165
+ * Whether to show the tick marks. Only used when the slider is in discrete mode.
166
+ * <li>{@code tickVisibilityMode}: Mode to specify the visibility of tick marks. Only used when
167
+ * the slider is in discrete mode.
162
168
* <li>{@code trackColorActive}: The color of the active part of the track.
163
169
* <li>{@code trackColorInactive}: The color of the inactive part of the track.
164
170
* <li>{@code trackColor}: The color of the whole track. This is a short hand for setting both the
210
216
* @attr ref com.google.android.material.R.styleable#Slider_tickColorActive
211
217
* @attr ref com.google.android.material.R.styleable#Slider_tickColorInactive
212
218
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
219
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
213
220
* @attr ref com.google.android.material.R.styleable#Slider_trackColor
214
221
* @attr ref com.google.android.material.R.styleable#Slider_trackColorActive
215
222
* @attr ref com.google.android.material.R.styleable#Slider_trackColorInactive
@@ -352,7 +359,7 @@ abstract class BaseSlider<
352
359
private int focusedThumbIdx = -1 ;
353
360
private float stepSize = 0.0f ;
354
361
private float [] ticksCoordinates ;
355
- private boolean tickVisible = true ;
362
+ private int tickVisibilityMode ;
356
363
private int tickActiveRadius ;
357
364
private int tickInactiveRadius ;
358
365
private int trackWidth ;
@@ -566,7 +573,10 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
566
573
? haloColor
567
574
: AppCompatResources .getColorStateList (context , R .color .material_slider_halo_color ));
568
575
569
- tickVisible = a .getBoolean (R .styleable .Slider_tickVisible , true );
576
+ tickVisibilityMode = a .hasValue (R .styleable .Slider_tickVisibilityMode )
577
+ ? a .getInt (R .styleable .Slider_tickVisibilityMode , -1 )
578
+ : convertToTickVisibilityMode (a .getBoolean (R .styleable .Slider_tickVisible , true ));
579
+
570
580
boolean hasTickColor = a .hasValue (R .styleable .Slider_tickColor );
571
581
int tickColorInactiveRes =
572
582
hasTickColor ? R .styleable .Slider_tickColor : R .styleable .Slider_tickColorInactive ;
@@ -1768,22 +1778,61 @@ public void setTickInactiveTintList(@NonNull ColorStateList tickColor) {
1768
1778
/**
1769
1779
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
1770
1780
*
1771
- * @see #setTickVisible(boolean)
1772
1781
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1773
1782
*/
1774
1783
public boolean isTickVisible () {
1775
- return tickVisible ;
1784
+ switch (tickVisibilityMode ) {
1785
+ case TICK_VISIBILITY_VISIBLE_ALL :
1786
+ case TICK_VISIBILITY_AUTO_LIMIT :
1787
+ return true ;
1788
+ case TICK_VISIBILITY_AUTO_HIDE :
1789
+ return getDesiredTickCount () <= getMaxTickCount ();
1790
+ case TICK_VISIBILITY_HIDDEN :
1791
+ return false ;
1792
+ default :
1793
+ throw new RuntimeException ("Unexpected tickVisibilityMode: " + tickVisibilityMode );
1794
+ }
1776
1795
}
1777
1796
1778
1797
/**
1779
1798
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
1780
1799
*
1781
1800
* @param tickVisible The visibility of tick marks.
1782
1801
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1802
+ * @deprecated Use {@link #setTickVisibilityMode(int)} instead.
1783
1803
*/
1804
+ @ Deprecated
1784
1805
public void setTickVisible (boolean tickVisible ) {
1785
- if (this .tickVisible != tickVisible ) {
1786
- this .tickVisible = tickVisible ;
1806
+ setTickVisibilityMode (convertToTickVisibilityMode (tickVisible ));
1807
+ }
1808
+
1809
+ @ TickVisibilityMode
1810
+ private int convertToTickVisibilityMode (boolean tickVisible ) {
1811
+ return tickVisible
1812
+ ? TICK_VISIBILITY_AUTO_LIMIT
1813
+ : TICK_VISIBILITY_HIDDEN ;
1814
+ }
1815
+
1816
+ /**
1817
+ * Returns the current tick visibility mode.
1818
+ *
1819
+ * @see #setTickVisibilityMode(int)
1820
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1821
+ */
1822
+ @ TickVisibilityMode
1823
+ public int getTickVisibilityMode () {
1824
+ return tickVisibilityMode ;
1825
+ }
1826
+
1827
+ /**
1828
+ * Sets the tick visibility mode. Only used when the slider is in discrete mode.
1829
+ *
1830
+ * @see #getTickVisibilityMode()
1831
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1832
+ */
1833
+ public void setTickVisibilityMode (@ TickVisibilityMode int tickVisibilityMode ) {
1834
+ if (this .tickVisibilityMode != tickVisibilityMode ) {
1835
+ this .tickVisibilityMode = tickVisibilityMode ;
1787
1836
postInvalidate ();
1788
1837
}
1789
1838
}
@@ -2337,24 +2386,60 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
2337
2386
updateHaloHotspot ();
2338
2387
}
2339
2388
2340
- private void maybeCalculateTicksCoordinates () {
2389
+ private void updateTicksCoordinates () {
2390
+ validateConfigurationIfDirty ();
2391
+
2341
2392
if (stepSize <= 0.0f ) {
2393
+ updateTicksCoordinates (/* tickCount= */ 0 );
2342
2394
return ;
2343
2395
}
2344
2396
2345
- validateConfigurationIfDirty ();
2397
+ final int tickCount ;
2398
+ switch (tickVisibilityMode ) {
2399
+ case TICK_VISIBILITY_VISIBLE_ALL :
2400
+ tickCount = getDesiredTickCount ();
2401
+ break ;
2402
+ case TICK_VISIBILITY_AUTO_LIMIT :
2403
+ tickCount = min (getDesiredTickCount (), getMaxTickCount ());
2404
+ break ;
2405
+ case TICK_VISIBILITY_AUTO_HIDE :
2406
+ int desiredTickCount = getDesiredTickCount ();
2407
+ tickCount = desiredTickCount <= getMaxTickCount () ? desiredTickCount : 0 ;
2408
+ break ;
2409
+ case TICK_VISIBILITY_HIDDEN :
2410
+ tickCount = 0 ;
2411
+ break ;
2412
+ default :
2413
+ throw new RuntimeException ("Unexpected tickVisibilityMode: " + tickVisibilityMode );
2414
+ }
2415
+
2416
+ updateTicksCoordinates (tickCount );
2417
+ }
2418
+
2419
+ private int getDesiredTickCount () {
2420
+ return (int ) ((valueTo - valueFrom ) / stepSize + 1 );
2421
+ }
2422
+
2423
+ private int getMaxTickCount () {
2424
+ return trackWidth / minTickSpacing + 1 ;
2425
+ }
2426
+
2427
+ private void updateTicksCoordinates (int tickCount ) {
2428
+ if (tickCount == 0 ) {
2429
+ ticksCoordinates = null ;
2430
+ return ;
2431
+ }
2346
2432
2347
- int tickCount = (int ) ((valueTo - valueFrom ) / stepSize + 1 );
2348
- // Limit the tickCount if they will be too dense.
2349
- tickCount = min (tickCount , trackWidth / minTickSpacing + 1 );
2350
2433
if (ticksCoordinates == null || ticksCoordinates .length != tickCount * 2 ) {
2351
2434
ticksCoordinates = new float [tickCount * 2 ];
2352
2435
}
2353
2436
2354
2437
float interval = trackWidth / (float ) (tickCount - 1 );
2438
+ float trackCenterY = calculateTrackCenter ();
2439
+
2355
2440
for (int i = 0 ; i < tickCount * 2 ; i += 2 ) {
2356
2441
ticksCoordinates [i ] = trackSidePadding + i / 2f * interval ;
2357
- ticksCoordinates [i + 1 ] = calculateTrackCenter () ;
2442
+ ticksCoordinates [i + 1 ] = trackCenterY ;
2358
2443
}
2359
2444
2360
2445
if (isVertical ()) {
@@ -2367,7 +2452,7 @@ private void updateTrackWidth(int width) {
2367
2452
trackWidth = max (width - trackSidePadding * 2 , 0 );
2368
2453
2369
2454
// Update the visible tick coordinates.
2370
- maybeCalculateTicksCoordinates ();
2455
+ updateTicksCoordinates ();
2371
2456
}
2372
2457
2373
2458
private void updateHaloHotspot () {
@@ -2404,7 +2489,7 @@ protected void onDraw(@NonNull Canvas canvas) {
2404
2489
validateConfigurationIfDirty ();
2405
2490
2406
2491
// Update the visible tick coordinates.
2407
- maybeCalculateTicksCoordinates ();
2492
+ updateTicksCoordinates ();
2408
2493
}
2409
2494
2410
2495
super .onDraw (canvas );
@@ -2703,7 +2788,7 @@ private float[] getCornerRadii(float leftSide, float rightSide) {
2703
2788
}
2704
2789
2705
2790
private void maybeDrawTicks (@ NonNull Canvas canvas ) {
2706
- if (! tickVisible || stepSize <= 0.0f ) {
2791
+ if (ticksCoordinates == null || ticksCoordinates . length == 0 ) {
2707
2792
return ;
2708
2793
}
2709
2794
0 commit comments