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 ;
@@ -299,7 +303,7 @@ abstract class BaseSlider<
299
303
private int focusedThumbIdx = -1 ;
300
304
private float stepSize = 0.0f ;
301
305
private float [] ticksCoordinates ;
302
- private boolean tickVisible = true ;
306
+ private int tickVisibilityMode ;
303
307
private int tickActiveRadius ;
304
308
private int tickInactiveRadius ;
305
309
private int trackWidth ;
@@ -471,7 +475,10 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
471
475
? haloColor
472
476
: AppCompatResources .getColorStateList (context , R .color .material_slider_halo_color ));
473
477
474
- tickVisible = a .getBoolean (R .styleable .Slider_tickVisible , true );
478
+ tickVisibilityMode = a .hasValue (R .styleable .Slider_tickVisibilityMode )
479
+ ? a .getInt (R .styleable .Slider_tickVisibilityMode , -1 )
480
+ : convertToTickVisibilityMode (a .getBoolean (R .styleable .Slider_tickVisible , true ));
481
+
475
482
boolean hasTickColor = a .hasValue (R .styleable .Slider_tickColor );
476
483
int tickColorInactiveRes =
477
484
hasTickColor ? R .styleable .Slider_tickColor : R .styleable .Slider_tickColorInactive ;
@@ -1526,22 +1533,61 @@ public void setTickInactiveTintList(@NonNull ColorStateList tickColor) {
1526
1533
/**
1527
1534
* Returns whether the tick marks are visible. Only used when the slider is in discrete mode.
1528
1535
*
1529
- * @see #setTickVisible(boolean)
1530
1536
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1531
1537
*/
1532
1538
public boolean isTickVisible () {
1533
- return tickVisible ;
1539
+ switch (tickVisibilityMode ) {
1540
+ case TICK_VISIBILITY_VISIBLE_ALL :
1541
+ case TICK_VISIBILITY_AUTO_LIMIT :
1542
+ return true ;
1543
+ case TICK_VISIBILITY_AUTO_HIDE :
1544
+ return getDesiredTickCount () <= getMaxTickCount ();
1545
+ case TICK_VISIBILITY_HIDDEN :
1546
+ return false ;
1547
+ default :
1548
+ throw new RuntimeException ("isTickVisible() is not implemented for tickVisibilityMode=" + tickVisibilityMode );
1549
+ }
1534
1550
}
1535
1551
1536
1552
/**
1537
1553
* Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
1538
1554
*
1539
1555
* @param tickVisible The visibility of tick marks.
1540
1556
* @attr ref com.google.android.material.R.styleable#Slider_tickVisible
1557
+ * @deprecated Use {@link #setTickVisibilityMode(int)} instead.
1541
1558
*/
1559
+ @ Deprecated
1542
1560
public void setTickVisible (boolean tickVisible ) {
1543
- if (this .tickVisible != tickVisible ) {
1544
- this .tickVisible = tickVisible ;
1561
+ setTickVisibilityMode (convertToTickVisibilityMode (tickVisible ));
1562
+ }
1563
+
1564
+ @ TickVisibilityMode
1565
+ private int convertToTickVisibilityMode (boolean tickVisible ) {
1566
+ return tickVisible
1567
+ ? TICK_VISIBILITY_AUTO_LIMIT
1568
+ : TICK_VISIBILITY_HIDDEN ;
1569
+ }
1570
+
1571
+ /**
1572
+ * Returns the current tick visibility mode.
1573
+ *
1574
+ * @see #setTickVisibilityMode(int)
1575
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1576
+ */
1577
+ @ TickVisibilityMode
1578
+ public int getTickVisibilityMode () {
1579
+ return tickVisibilityMode ;
1580
+ }
1581
+
1582
+ /**
1583
+ * Sets the tick visibility mode. Only used when the slider is in discrete mode.
1584
+ *
1585
+ * @see #getTickVisibilityMode()
1586
+ * @attr ref com.google.android.material.R.styleable#Slider_tickVisibilityMode
1587
+ */
1588
+ public void setTickVisibilityMode (@ TickVisibilityMode int tickVisibilityMode ) {
1589
+ if (this .tickVisibilityMode != tickVisibilityMode ) {
1590
+ this .tickVisibilityMode = tickVisibilityMode ;
1545
1591
postInvalidate ();
1546
1592
}
1547
1593
}
@@ -1716,24 +1762,60 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
1716
1762
updateHaloHotspot ();
1717
1763
}
1718
1764
1719
- private void maybeCalculateTicksCoordinates () {
1765
+ private void updateTicksCoordinates () {
1766
+ validateConfigurationIfDirty ();
1767
+
1720
1768
if (stepSize <= 0.0f ) {
1769
+ updateTicksCoordinates (/* tickCount= */ 0 );
1721
1770
return ;
1722
1771
}
1723
1772
1724
- validateConfigurationIfDirty ();
1773
+ final int tickCount ;
1774
+ switch (tickVisibilityMode ) {
1775
+ case TICK_VISIBILITY_VISIBLE_ALL :
1776
+ tickCount = getDesiredTickCount ();
1777
+ break ;
1778
+ case TICK_VISIBILITY_AUTO_LIMIT :
1779
+ tickCount = min (getDesiredTickCount (), getMaxTickCount ());
1780
+ break ;
1781
+ case TICK_VISIBILITY_AUTO_HIDE :
1782
+ int desiredTickCount = getDesiredTickCount ();
1783
+ tickCount = desiredTickCount <= getMaxTickCount () ? desiredTickCount : 0 ;
1784
+ break ;
1785
+ case TICK_VISIBILITY_HIDDEN :
1786
+ tickCount = 0 ;
1787
+ break ;
1788
+ default :
1789
+ throw new RuntimeException ("Calculation of tick coordinates is not implemented for tickVisibilityMode=" + tickVisibilityMode );
1790
+ }
1791
+
1792
+ updateTicksCoordinates (tickCount );
1793
+ }
1794
+
1795
+ private int getDesiredTickCount () {
1796
+ return (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1797
+ }
1798
+
1799
+ private int getMaxTickCount () {
1800
+ return trackWidth / (trackHeight * 2 ) + 1 ;
1801
+ }
1802
+
1803
+ private void updateTicksCoordinates (int tickCount ) {
1804
+ if (tickCount == 0 ) {
1805
+ ticksCoordinates = null ;
1806
+ return ;
1807
+ }
1725
1808
1726
- int tickCount = (int ) ((valueTo - valueFrom ) / stepSize + 1 );
1727
- // Limit the tickCount if they will be too dense.
1728
- tickCount = min (tickCount , trackWidth / (trackHeight * 2 ) + 1 );
1729
1809
if (ticksCoordinates == null || ticksCoordinates .length != tickCount * 2 ) {
1730
1810
ticksCoordinates = new float [tickCount * 2 ];
1731
1811
}
1732
1812
1733
1813
float interval = trackWidth / (float ) (tickCount - 1 );
1814
+ float trackCenterY = calculateTrackCenter ();
1815
+
1734
1816
for (int i = 0 ; i < tickCount * 2 ; i += 2 ) {
1735
1817
ticksCoordinates [i ] = trackSidePadding + i / 2f * interval ;
1736
- ticksCoordinates [i + 1 ] = calculateTrackCenter () ;
1818
+ ticksCoordinates [i + 1 ] = trackCenterY ;
1737
1819
}
1738
1820
}
1739
1821
@@ -1742,7 +1824,7 @@ private void updateTrackWidth(int width) {
1742
1824
trackWidth = max (width - trackSidePadding * 2 , 0 );
1743
1825
1744
1826
// Update the visible tick coordinates.
1745
- maybeCalculateTicksCoordinates ();
1827
+ updateTicksCoordinates ();
1746
1828
}
1747
1829
1748
1830
private void updateHaloHotspot () {
@@ -1771,7 +1853,7 @@ protected void onDraw(@NonNull Canvas canvas) {
1771
1853
validateConfigurationIfDirty ();
1772
1854
1773
1855
// Update the visible tick coordinates.
1774
- maybeCalculateTicksCoordinates ();
1856
+ updateTicksCoordinates ();
1775
1857
}
1776
1858
1777
1859
super .onDraw (canvas );
@@ -1847,7 +1929,7 @@ private void drawActiveTrack(@NonNull Canvas canvas, int width, int yCenter) {
1847
1929
}
1848
1930
1849
1931
private void maybeDrawTicks (@ NonNull Canvas canvas ) {
1850
- if (! tickVisible || stepSize <= 0.0f ) {
1932
+ if (ticksCoordinates == null || ticksCoordinates . length == 0 ) {
1851
1933
return ;
1852
1934
}
1853
1935
0 commit comments