24
24
import static com .google .android .material .slider .LabelFormatter .LABEL_GONE ;
25
25
import static com .google .android .material .slider .LabelFormatter .LABEL_VISIBLE ;
26
26
import static com .google .android .material .slider .LabelFormatter .LABEL_WITHIN_BOUNDS ;
27
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_AUTO_HIDE ;
28
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_AUTO_LIMIT ;
29
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_HIDDEN ;
30
+ import static com .google .android .material .slider .TickVisibilityMode .TICK_VISIBILITY_VISIBLE_ALL ;
27
31
import static com .google .android .material .theme .overlay .MaterialThemeOverlay .wrap ;
28
32
import static java .lang .Float .compare ;
29
33
import static java .lang .Math .abs ;
@@ -301,7 +305,7 @@ private interface TooltipDrawableFactory {
301
305
private int focusedThumbIdx = -1 ;
302
306
private float stepSize = 0.0f ;
303
307
private float [] ticksCoordinates ;
304
- private boolean tickVisible = true ;
308
+ private int tickVisibilityMode ;
305
309
private int trackWidth ;
306
310
private boolean forceDrawCompatHalo ;
307
311
private boolean isLongPress = false ;
@@ -481,7 +485,10 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
481
485
? haloColor
482
486
: AppCompatResources .getColorStateList (context , R .color .material_slider_halo_color ));
483
487
484
- tickVisible = a .getBoolean (R .styleable .Slider_tickVisible , true );
488
+ tickVisibilityMode = a .hasValue (R .styleable .Slider_tickVisibilityMode )
489
+ ? a .getInt (R .styleable .Slider_tickVisibilityMode , -1 )
490
+ : convertToTickVisibilityMode (a .getBoolean (R .styleable .Slider_tickVisible , true ));
491
+
485
492
boolean hasTickColor = a .hasValue (R .styleable .Slider_tickColor );
486
493
int tickColorInactiveRes =
487
494
hasTickColor ? R .styleable .Slider_tickColor : R .styleable .Slider_tickColorInactive ;
@@ -1485,22 +1492,61 @@ public void setTickInactiveTintList(@NonNull ColorStateList tickColor) {
1485
1492
/**
1486
1493
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
1487
1494
*
1488
- * @see #setTickVisible(boolean)
1489
1495
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1490
1496
*/
1491
1497
public boolean isTickVisible () {
1492
- return tickVisible ;
1498
+ switch (tickVisibilityMode ) {
1499
+ case TICK_VISIBILITY_VISIBLE_ALL :
1500
+ case TICK_VISIBILITY_AUTO_LIMIT :
1501
+ return true ;
1502
+ case TICK_VISIBILITY_AUTO_HIDE :
1503
+ return getDesiredTickCount () <= getMaxTickCount ();
1504
+ case TICK_VISIBILITY_HIDDEN :
1505
+ return false ;
1506
+ default :
1507
+ throw new RuntimeException ("isTickVisible() is not implemented for tickVisibilityMode=" + tickVisibilityMode );
1508
+ }
1493
1509
}
1494
1510
1495
1511
/**
1496
1512
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
1497
1513
*
1498
1514
* @param tickVisible The visibility of tick marks.
1499
1515
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1516
+ * @deprecated Use {@link #setTickVisibilityMode(int)} instead.
1500
1517
*/
1518
+ @ Deprecated
1501
1519
public void setTickVisible (boolean tickVisible ) {
1502
- if (this .tickVisible != tickVisible ) {
1503
- this .tickVisible = tickVisible ;
1520
+ setTickVisibilityMode (convertToTickVisibilityMode (tickVisible ));
1521
+ }
1522
+
1523
+ @ TickVisibilityMode
1524
+ private int convertToTickVisibilityMode (boolean tickVisible ) {
1525
+ return tickVisible
1526
+ ? TICK_VISIBILITY_AUTO_LIMIT
1527
+ : TICK_VISIBILITY_HIDDEN ;
1528
+ }
1529
+
1530
+ /**
1531
+ * Returns the current tick visibility mode.
1532
+ *
1533
+ * @see #setTickVisibilityMode(int)
1534
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1535
+ */
1536
+ @ TickVisibilityMode
1537
+ public int getTickVisibilityMode () {
1538
+ return tickVisibilityMode ;
1539
+ }
1540
+
1541
+ /**
1542
+ * Sets the tick visibility mode. Only used when the slider is in discrete mode.
1543
+ *
1544
+ * @see #getTickVisibilityMode()
1545
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1546
+ */
1547
+ public void setTickVisibilityMode (@ TickVisibilityMode int tickVisibilityMode ) {
1548
+ if (this .tickVisibilityMode != tickVisibilityMode ) {
1549
+ this .tickVisibilityMode = tickVisibilityMode ;
1504
1550
postInvalidate ();
1505
1551
}
1506
1552
}
@@ -1675,24 +1721,58 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
1675
1721
updateHaloHotspot ();
1676
1722
}
1677
1723
1678
- private void maybeCalculateTicksCoordinates () {
1724
+ private void updateTicksCoordinates () {
1679
1725
if (stepSize <= 0.0f ) {
1726
+ updateTicksCoordinates (/* tickCount= */ 0 );
1680
1727
return ;
1681
1728
}
1682
1729
1683
- validateConfigurationIfDirty ();
1730
+ final int tickCount ;
1731
+ switch (tickVisibilityMode ) {
1732
+ case TICK_VISIBILITY_VISIBLE_ALL :
1733
+ tickCount = getDesiredTickCount ();
1734
+ break ;
1735
+ case TICK_VISIBILITY_AUTO_LIMIT :
1736
+ tickCount = min (getDesiredTickCount (), getMaxTickCount ());
1737
+ break ;
1738
+ case TICK_VISIBILITY_AUTO_HIDE :
1739
+ int desiredTickCount = getDesiredTickCount ();
1740
+ tickCount = desiredTickCount <= getMaxTickCount () ? desiredTickCount : 0 ;
1741
+ break ;
1742
+ case TICK_VISIBILITY_HIDDEN :
1743
+ tickCount = 0 ;
1744
+ break ;
1745
+ default :
1746
+ throw new RuntimeException ("Calculation of tick coordinates is not implemented for tickVisibilityMode=" + tickVisibilityMode );
1747
+ }
1748
+
1749
+ updateTicksCoordinates (tickCount );
1750
+ }
1751
+
1752
+ private int getDesiredTickCount () {
1753
+ return (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1754
+ }
1755
+
1756
+ private int getMaxTickCount () {
1757
+ return trackWidth / (trackHeight * 2 ) + 1 ;
1758
+ }
1759
+
1760
+ private void updateTicksCoordinates (int tickCount ) {
1761
+ if (tickCount == 0 ) {
1762
+ ticksCoordinates = null ;
1763
+ return ;
1764
+ }
1684
1765
1685
- int tickCount = (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1686
- // Limit the tickCount if they will be too dense.
1687
- tickCount = min (tickCount , trackWidth / (trackHeight * 2 ) + 1 );
1688
1766
if (ticksCoordinates == null || ticksCoordinates .length != tickCount * 2 ) {
1689
1767
ticksCoordinates = new float [tickCount * 2 ];
1690
1768
}
1691
1769
1692
1770
float interval = trackWidth / (float ) (tickCount - 1 );
1771
+ float trackCenterY = calculateTrackCenter ();
1772
+
1693
1773
for (int i = 0 ; i < tickCount * 2 ; i += 2 ) {
1694
1774
ticksCoordinates [i ] = trackSidePadding + i / 2 * interval ;
1695
- ticksCoordinates [i + 1 ] = calculateTrackCenter () ;
1775
+ ticksCoordinates [i + 1 ] = trackCenterY ;
1696
1776
}
1697
1777
}
1698
1778
@@ -1701,7 +1781,7 @@ private void updateTrackWidth(int width) {
1701
1781
trackWidth = max (width - trackSidePadding * 2 , 0 );
1702
1782
1703
1783
// Update the visible tick coordinates.
1704
- maybeCalculateTicksCoordinates ();
1784
+ updateTicksCoordinates ();
1705
1785
}
1706
1786
1707
1787
private void updateHaloHotspot () {
@@ -1730,7 +1810,7 @@ protected void onDraw(@NonNull Canvas canvas) {
1730
1810
validateConfigurationIfDirty ();
1731
1811
1732
1812
// Update the visible tick coordinates.
1733
- maybeCalculateTicksCoordinates ();
1813
+ updateTicksCoordinates ();
1734
1814
}
1735
1815
1736
1816
super .onDraw (canvas );
@@ -1807,7 +1887,7 @@ private void drawActiveTrack(@NonNull Canvas canvas, int width, int yCenter) {
1807
1887
}
1808
1888
1809
1889
private void maybeDrawTicks (@ NonNull Canvas canvas ) {
1810
- if (! tickVisible || stepSize <= 0.0f ) {
1890
+ if (ticksCoordinates == null || ticksCoordinates . length == 0 ) {
1811
1891
return ;
1812
1892
}
1813
1893
0 commit comments