Skip to content

Commit e62e66d

Browse files
committed
[Slider] Add ability to specify purely visual tick count in continuous mode
PiperOrigin-RevId: 764271536
1 parent ab52e6a commit e62e66d

File tree

7 files changed

+108
-29
lines changed

7 files changed

+108
-29
lines changed

catalog/java/io/material/catalog/slider/SliderContinuousDemoFragment.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import io.material.catalog.R;
2020

21+
import static java.lang.Math.max;
22+
2123
import android.os.Bundle;
2224
import android.view.LayoutInflater;
2325
import android.view.View;
@@ -55,6 +57,18 @@ public View onCreateDemoView(
5557
setUpSlider(sliderTwo, view.findViewById(R.id.value_2), "%.0f");
5658
setUpSlider(sliderThree, view.findViewById(R.id.value_3), "%.2f");
5759

60+
view.findViewById(R.id.add_tick).setOnClickListener(v -> {
61+
sliderOne.setContinuousModeTickCount(sliderOne.getContinuousModeTickCount() + 1);
62+
sliderTwo.setContinuousModeTickCount(sliderTwo.getContinuousModeTickCount() + 1);
63+
sliderThree.setContinuousModeTickCount(sliderThree.getContinuousModeTickCount() + 1);
64+
});
65+
66+
view.findViewById(R.id.remove_tick).setOnClickListener(v -> {
67+
sliderOne.setContinuousModeTickCount(max(sliderOne.getContinuousModeTickCount() - 1, 0));
68+
sliderTwo.setContinuousModeTickCount(max(sliderTwo.getContinuousModeTickCount() - 1, 0));
69+
sliderThree.setContinuousModeTickCount(max(sliderThree.getContinuousModeTickCount() - 1, 0));
70+
});
71+
5872
return view;
5973
}
6074

catalog/java/io/material/catalog/slider/res/layout/cat_slider_demo_continuous.xml

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
-->
17-
<ScrollView
18-
xmlns:android="http://schemas.android.com/apk/res/android"
19-
android:layout_width="match_parent"
20-
android:layout_height="match_parent">
17+
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:layout_width="match_parent"
19+
android:layout_height="match_parent"
20+
xmlns:app="http://schemas.android.com/apk/res-auto">
2121

2222
<LinearLayout
2323
android:layout_width="match_parent"
@@ -114,5 +114,25 @@
114114
android:layout_gravity="center_horizontal"
115115
android:checked="true"
116116
android:text="@string/cat_slider_enabled"/>
117+
118+
<com.google.android.material.button.MaterialButtonGroup
119+
android:layout_width="wrap_content"
120+
android:layout_height="wrap_content"
121+
android:layout_gravity="center_horizontal"
122+
android:layout_marginTop="16dp">
123+
124+
<Button
125+
android:id="@+id/add_tick"
126+
android:layout_width="wrap_content"
127+
android:layout_height="wrap_content"
128+
android:text="@string/cat_slider_add_tick" />
129+
130+
<Button
131+
android:id="@+id/remove_tick"
132+
android:layout_width="wrap_content"
133+
android:layout_height="wrap_content"
134+
android:text="@string/cat_slider_remove_tick" />
135+
136+
</com.google.android.material.button.MaterialButtonGroup>
117137
</LinearLayout>
118138
</ScrollView>

catalog/java/io/material/catalog/slider/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
</string>
3636

3737
<string name="cat_slider_enabled" description="The label for a switch controlling enabled state[CHAR LIMIT=NONE]">Enabled</string>
38+
<string name="cat_slider_add_tick" description="The label for a button that adds a tick to the slider[CHAR LIMIT=NONE]">Add Tick</string>
39+
<string name="cat_slider_remove_tick" description="The label for a button that removes a tick from the slider[CHAR LIMIT=NONE]">Remove Tick</string>
3840
<string name="cat_slider_vertical" description="The label for a switch controlling vertical orientation [CHAR LIMIT=NONE]">Vertical</string>
3941
<string name="cat_slider_set" description="The label for a set button [CHAR LIMIT=NONE]">Set</string>
4042
<string name="cat_slider_title_1" description="The title for the first demonstration slider [CHAR LIMIT=NONE]">This one goes to eleven</string>

docs/components/Slider.md

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -292,30 +292,31 @@ slider also has tick marks.
292292

293293
#### Track attributes
294294

295-
| Element | Attribute | Related method(s) | Default value |
296-
|--------------------------------------------|------------------------------|-------------------------------------------------------------|--------------------------------------|
297-
| **Orientation** | `android:orientation` | `setOrientation`<br/>`isVertical` | `horizontal` |
298-
| **Centered** | `android:centered` | `setCentered`<br/>`isCentered` | `false` |
299-
| **Min value** | `android:valueFrom` | `setValueFrom`<br/>`getValueFrom` | N/A |
300-
| **Max value** | `android:valueTo` | `setValueTo`<br/>`getValueTo` | N/A |
301-
| **Step size (discrete)** | `android:stepSize` | `setStepSize`<br/>`getStepSize` | N/A |
302-
| **Initial selected value (Slider)** | `android:value` | `setValue`<br/>`getValue` | N/A |
303-
| **Initial selected values (RangeSlider)** | `app:values` | `setValues`<br/>`getValues` | N/A |
304-
| **Height** | `app:trackHeight` | `setTrackHeight`<br/>`getTrackHeight` | `16dp` |
305-
| **Color** | `app:trackColor` | `setTrackTintList`<br/>`getTrackTintList` | `null` |
306-
| **Color for track's active part** | `app:trackColorActive` | `setTrackActiveTintList`<br/>`getTrackActiveTintList` | `?attr/colorPrimary` |
307-
| **Color for track's inactive part** | `app:trackColorInactive` | `setTrackInactiveTintList`<br/>`getTrackInactiveTintList` | `?attr/colorSurfaceContainerHighest` |
308-
| **Corner size** | `app:trackCornerSize` | `setTrackCornerSize`<br/>`getTrackCornerSize` | `trackHeight / 2` |
309-
| **Inside corner size** | `app:trackInsideCornerSize` | `setTrackInsideCornerSize`<br/>`getTrackInsideCornerSize` | `2dp` |
310-
| **Stop indicator size** | `app:trackStopIndicatorSize` | `setTrackStopIndicatorSize`<br/>`getTrackStopIndicatorSize` | `4dp` |
311-
| **Minimum separation for adjacent thumbs** | `app:minSeparation` | `setMinSeparation`<br/>`getMinSeparation` | `0dp` |
312-
| **Active start icon** | `app:trackIconActiveStart` | `setTrackIconActiveStart`<br/>`getTrackIconActiveStart` | `null` |
313-
| **Active end icon** | `app:trackIconActiveEnd` | `setTrackIconActiveEnd`<br/>`getTrackIconActiveEnd` | `null` |
314-
| **Active icon color** | `app:trackIconActiveColor` | `setTrackIconActiveColor`<br/>`getTrackIconActiveColor` | N/A |
315-
| **Inactive start icon** | `app:trackIconInactiveStart` | `setTrackIconInactiveStart`<br/>`getTrackIconInactiveStart` | `null` |
316-
| **Inactive end icon** | `app:trackIconInactiveEnd` | `setTrackIconInactiveEnd`<br/>`getTrackIconInactiveEnd` | `null` |
317-
| **Inactive icon color** | `app:trackIconInactiveColor` | `setTrackIconInactiveColor`<br/>`getTrackIconInactiveColor` | N/A |
318-
| **Icon size** | `app:trackIconSize` | `setTrackIconSize`<br/>`getTrackIconSize` | N/A |
295+
| Element | Attribute | Related method(s) | Default value |
296+
|--------------------------------------------|-------------------------------|----------------------------------------------------------------|--------------------------------------|
297+
| **Orientation** | `android:orientation` | `setOrientation`<br/>`isVertical` | `horizontal` |
298+
| **Min value** | `android:valueFrom` | `setValueFrom`<br/>`getValueFrom` | N/A |
299+
| **Max value** | `android:valueTo` | `setValueTo`<br/>`getValueTo` | N/A |
300+
| **Step size (discrete)** | `android:stepSize` | `setStepSize`<br/>`getStepSize` | N/A |
301+
| **Initial selected value (Slider)** | `android:value` | `setValue`<br/>`getValue` | N/A |
302+
| **Initial selected values (RangeSlider)** | `app:values` | `setValues`<br/>`getValues` | N/A |
303+
| **Centered** | `app:centered` | `setCentered`<br/>`isCentered` | `false` |
304+
| **Continuous mode tick count** | `app:continuousModeTickCount` | `setContinuousModeTickCount`<br/>`getContinuousModeTickCount` | 0 |
305+
| **Height** | `app:trackHeight` | `setTrackHeight`<br/>`getTrackHeight` | `16dp` |
306+
| **Color** | `app:trackColor` | `setTrackTintList`<br/>`getTrackTintList` | `null` |
307+
| **Color for track's active part** | `app:trackColorActive` | `setTrackActiveTintList`<br/>`getTrackActiveTintList` | `?attr/colorPrimary` |
308+
| **Color for track's inactive part** | `app:trackColorInactive` | `setTrackInactiveTintList`<br/>`getTrackInactiveTintList` | `?attr/colorSurfaceContainerHighest` |
309+
| **Corner size** | `app:trackCornerSize` | `setTrackCornerSize`<br/>`getTrackCornerSize` | `trackHeight / 2` |
310+
| **Inside corner size** | `app:trackInsideCornerSize` | `setTrackInsideCornerSize`<br/>`getTrackInsideCornerSize` | `2dp` |
311+
| **Stop indicator size** | `app:trackStopIndicatorSize` | `setTrackStopIndicatorSize`<br/>`getTrackStopIndicatorSize` | `4dp` |
312+
| **Minimum separation for adjacent thumbs** | `app:minSeparation` | `setMinSeparation`<br/>`getMinSeparation` | `0dp` |
313+
| **Active start icon** | `app:trackIconActiveStart` | `setTrackIconActiveStart`<br/>`getTrackIconActiveStart` | `null` |
314+
| **Active end icon** | `app:trackIconActiveEnd` | `setTrackIconActiveEnd`<br/>`getTrackIconActiveEnd` | `null` |
315+
| **Active icon color** | `app:trackIconActiveColor` | `setTrackIconActiveColor`<br/>`getTrackIconActiveColor` | N/A |
316+
| **Inactive start icon** | `app:trackIconInactiveStart` | `setTrackIconInactiveStart`<br/>`getTrackIconInactiveStart` | `null` |
317+
| **Inactive end icon** | `app:trackIconInactiveEnd` | `setTrackIconInactiveEnd`<br/>`getTrackIconInactiveEnd` | `null` |
318+
| **Inactive icon color** | `app:trackIconInactiveColor` | `setTrackIconInactiveColor`<br/>`getTrackIconInactiveColor` | N/A |
319+
| **Icon size** | `app:trackIconSize` | `setTrackIconSize`<br/>`getTrackIconSize` | N/A |
319320

320321
**Note:** `app:trackColor` takes precedence over `app:trackColorActive` and
321322
`app:trackColorInative`. It's a shorthand for setting both values to the same

lib/java/com/google/android/material/slider/BaseSlider.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ abstract class BaseSlider<
257257
private static final String EXCEPTION_ILLEGAL_MIN_SEPARATION_STEP_SIZE =
258258
"minSeparation(%s) must be greater or equal and a multiple of stepSize(%s) when using"
259259
+ " stepSize(%s)";
260+
private static final String EXCEPTION_ILLEGAL_CONTINUOUS_MODE_TICK_COUNT =
261+
"The continuousModeTickCount(%s) must be greater than or equal to 0";
260262
private static final String WARNING_FLOATING_POINT_ERROR =
261263
"Floating point value used for %s(%s). Using floats can have rounding errors which may"
262264
+ " result in incorrect values. Instead, consider using integers with a custom"
@@ -371,6 +373,7 @@ abstract class BaseSlider<
371373
// The index of the currently focused thumb.
372374
private int focusedThumbIdx = -1;
373375
private float stepSize = 0.0f;
376+
private int continuousModeTickCount = 0;
374377
private float[] ticksCoordinates;
375378
private int tickVisibilityMode;
376379
private int tickActiveRadius;
@@ -544,6 +547,7 @@ private void processAttributes(Context context, AttributeSet attrs, int defStyle
544547
setValues(valueFrom);
545548
setCentered(a.getBoolean(R.styleable.Slider_centered, false));
546549
stepSize = a.getFloat(R.styleable.Slider_android_stepSize, 0.0f);
550+
continuousModeTickCount = a.getInt(R.styleable.Slider_continuousModeTickCount, 0);
547551

548552
float defaultMinTouchTargetSize = MaterialAttributes.resolveMinimumAccessibleTouchTarget(context);
549553
minTouchTargetSize =
@@ -977,6 +981,40 @@ public void setStepSize(float stepSize) {
977981
}
978982
}
979983

984+
/**
985+
* Returns the tick count used in continuous mode.
986+
*
987+
* @see #setContinuousModeTickCount(int)
988+
* @attr ref com.google.android.material.R.styleable#Slider_continuousModeTickCount
989+
*/
990+
public int getContinuousModeTickCount() {
991+
return continuousModeTickCount;
992+
}
993+
994+
/**
995+
* Sets the number of ticks to display in continuous mode. Default is 0.
996+
*
997+
* <p>This allows for showing purely visual ticks in continuous mode.
998+
*
999+
* <p>Setting this value to a negative value will result in an {@link IllegalArgumentException}.
1000+
*
1001+
* @param continuousModeTickCount The number of ticks that must be drawn in continuous mode count
1002+
* @throws IllegalArgumentException If the continuous mode tick count is less than 0
1003+
* @see #getContinuousModeTickCount()
1004+
* @attr ref com.google.android.material.R.styleable#Slider_continuousModeTickCount
1005+
*/
1006+
public void setContinuousModeTickCount(int continuousModeTickCount) {
1007+
if (continuousModeTickCount < 0) {
1008+
throw new IllegalArgumentException(
1009+
String.format(EXCEPTION_ILLEGAL_CONTINUOUS_MODE_TICK_COUNT, continuousModeTickCount));
1010+
}
1011+
if (this.continuousModeTickCount != continuousModeTickCount) {
1012+
this.continuousModeTickCount = continuousModeTickCount;
1013+
dirtyConfig = true;
1014+
postInvalidate();
1015+
}
1016+
}
1017+
9801018
/**
9811019
* Sets the custom thumb drawable which will be used for all value positions. Note that the custom
9821020
* drawable provided will be resized to match the thumb radius set by {@link #setThumbRadius(int)}
@@ -2485,8 +2523,9 @@ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
24852523
private void updateTicksCoordinates() {
24862524
validateConfigurationIfDirty();
24872525

2526+
// Continuous mode.
24882527
if (stepSize <= 0.0f) {
2489-
updateTicksCoordinates(/* tickCount= */ 0);
2528+
updateTicksCoordinates(continuousModeTickCount);
24902529
return;
24912530
}
24922531

lib/java/com/google/android/material/slider/res-public/values/public.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
<public name="sliderStyle" type="attr"/>
1919

2020
<public name="centered" type="attr" />
21+
<public name="continuousModeTickCount" type="attr" />
2122
<public name="haloColor" type="attr" />
2223
<public name="haloRadius" type="attr" />
2324
<public name="labelBehavior" type="attr" />

lib/java/com/google/android/material/slider/res/values/attrs.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
<attr name="android:enabled" />
2525
<attr name="android:orientation" />
2626
<attr name="centered" format="boolean" />
27+
<!-- The number of purely visual ticks to display in continuous mode. -->
28+
<attr name="continuousModeTickCount" format="integer" />
2729
<!-- The color of the slider's halo. -->
2830
<attr name="haloColor" format="color" />
2931
<!-- The radius of the halo. -->

0 commit comments

Comments
 (0)