2020
2121import android .content .Context ;
2222import android .content .res .TypedArray ;
23+ import android .os .Parcel ;
24+ import android .os .Parcelable ;
2325import android .util .AttributeSet ;
26+ import android .view .AbsSavedState ;
27+ import androidx .annotation .Dimension ;
2428import androidx .annotation .NonNull ;
2529import androidx .annotation .Nullable ;
30+ import com .google .android .material .internal .ThemeEnforcement ;
2631import com .google .android .material .slider .RangeSlider .OnChangeListener ;
2732import com .google .android .material .slider .RangeSlider .OnSliderTouchListener ;
2833import java .util .ArrayList ;
3742 * <p>{@code app:values}: <b>Optional.</b> The initial values of the range slider. If not specified,
3843 * the range slider will only have one value equal to {@code android:valueFrom}
3944 *
45+ * <p>{@code app:minSeparation}: <b>Optional.</b> The minimum distance between two thumbs that would
46+ * otherwise overlap.
47+ *
4048 * @attr ref com.google.android.material.R.styleable#RangeSlider_values
49+ * @attr ref com.google.android.material.R.styleable#RangeSlider_minSeparation
4150 */
4251public class RangeSlider extends BaseSlider <RangeSlider , OnChangeListener , OnSliderTouchListener > {
4352
53+ private float minSeparation ;
54+ private int separationUnit ;
55+
4456 public RangeSlider (@ NonNull Context context ) {
4557 this (context , null );
4658 }
@@ -51,13 +63,16 @@ public RangeSlider(@NonNull Context context, @Nullable AttributeSet attrs) {
5163
5264 public RangeSlider (@ NonNull Context context , @ Nullable AttributeSet attrs , int defStyleAttr ) {
5365 super (context , attrs , defStyleAttr );
54- TypedArray a = context .obtainStyledAttributes (attrs , new int [] {R .attr .values });
55-
56- if (a .hasValue (0 )) {
57- int valuesId = a .getResourceId (0 , 0 );
66+ TypedArray a =
67+ ThemeEnforcement .obtainStyledAttributes (
68+ context , attrs , R .styleable .RangeSlider , defStyleAttr , DEF_STYLE_RES );
69+ if (a .hasValue (R .styleable .RangeSlider_values )) {
70+ int valuesId = a .getResourceId (R .styleable .RangeSlider_values , 0 );
5871 TypedArray values = a .getResources ().obtainTypedArray (valuesId );
5972 setValues (convertToFloat (values ));
6073 }
74+
75+ minSeparation = a .getDimension (R .styleable .RangeSlider_minSeparation , 0 );
6176 a .recycle ();
6277 }
6378
@@ -104,4 +119,99 @@ private static List<Float> convertToFloat(TypedArray values) {
104119 }
105120 return ret ;
106121 }
122+
123+ /**
124+ * Returns the minimum separation between two thumbs
125+ *
126+ * @see #setMinSeparation(float)
127+ * @attr ref com.google.android.material.R.styleable#RangeSlider_minSeparation
128+ */
129+ @ Override
130+ public float getMinSeparation () {
131+ return minSeparation ;
132+ }
133+
134+ /**
135+ * Sets the minimum separation between two thumbs
136+ *
137+ * @see #getMinSeparation()
138+ * @attr ref com.google.android.material.R.styleable#RangeSlider_minSeparation
139+ */
140+ public void setMinSeparation (@ Dimension float minSeparation ) {
141+ this .minSeparation = minSeparation ;
142+ separationUnit = UNIT_PX ;
143+ setSeparationUnit (separationUnit );
144+ }
145+
146+ /**
147+ * Sets the minimum separation in the value scale. Useful to create minimum ranges, between
148+ * thumbs.
149+ *
150+ * @see #getMinSeparation()
151+ * @see #setMinSeparation(float)
152+ * @attr ref com.google.android.material.R.styleable#RangeSlider_minSeparation
153+ */
154+ public void setMinSeparationValue (float minSeparation ) {
155+ this .minSeparation = minSeparation ;
156+ separationUnit = UNIT_VALUE ;
157+ setSeparationUnit (separationUnit );
158+ }
159+
160+ @ Override
161+ @ NonNull
162+ public Parcelable onSaveInstanceState () {
163+ Parcelable superState = super .onSaveInstanceState ();
164+
165+ RangeSliderState sliderState = new RangeSliderState (superState );
166+ sliderState .minSeparation = this .minSeparation ;
167+ sliderState .separationUnit = this .separationUnit ;
168+
169+ return sliderState ;
170+ }
171+
172+ @ Override
173+ protected void onRestoreInstanceState (@ Nullable Parcelable state ) {
174+ RangeSliderState savedState = (RangeSliderState ) state ;
175+ super .onRestoreInstanceState (savedState .getSuperState ());
176+
177+ this .minSeparation = savedState .minSeparation ;
178+ this .separationUnit = savedState .separationUnit ;
179+ setSeparationUnit (separationUnit );
180+ }
181+
182+ static class RangeSliderState extends AbsSavedState {
183+
184+ private float minSeparation ;
185+ private int separationUnit ;
186+
187+ RangeSliderState (Parcelable superState ) {
188+ super (superState );
189+ }
190+
191+ private RangeSliderState (Parcel in ) {
192+ super ((Parcelable ) in .readParcelable (RangeSliderState .class .getClassLoader ()));
193+ minSeparation = in .readFloat ();
194+ separationUnit = in .readInt ();
195+ }
196+
197+ @ Override
198+ public void writeToParcel (Parcel out , int flags ) {
199+ super .writeToParcel (out , flags );
200+ out .writeFloat (minSeparation );
201+ out .writeInt (separationUnit );
202+ }
203+
204+ public static final Parcelable .Creator <RangeSliderState > CREATOR =
205+ new Parcelable .Creator <RangeSliderState >() {
206+ @ Override
207+ public RangeSliderState createFromParcel (Parcel in ) {
208+ return new RangeSliderState (in );
209+ }
210+
211+ @ Override
212+ public RangeSliderState [] newArray (int size ) {
213+ return new RangeSliderState [size ];
214+ }
215+ };
216+ }
107217}
0 commit comments