44import android .content .Context ;
55import android .content .res .TypedArray ;
66import android .graphics .Color ;
7+ import android .text .InputType ;
78import android .util .AttributeSet ;
89import android .view .View ;
10+ import android .widget .EditText ;
911import android .widget .SeekBar ;
1012import android .widget .TextView ;
1113
1214import androidx .annotation .NonNull ;
15+ import androidx .appcompat .app .AlertDialog ;
1316import androidx .preference .PreferenceViewHolder ;
1417import androidx .preference .SeekBarPreference ;
1518
@@ -23,8 +26,12 @@ public class CustomSeekBarPreference extends SeekBarPreference {
2326 private int mMin ;
2427 /** The textview associated by default to the preference */
2528 private TextView mTextView ;
29+ /** The seekbar widget associated to the preference, kept so a typed value can move it */
30+ private SeekBar mSeekBar ;
2631 /** Seekbar increment in case the max gets set */
2732 private final int mIncrement ;
33+ /** When true, tapping the value TextView opens a dialog to type an exact value */
34+ private boolean mTapToSetValueEnabled = false ;
2835
2936
3037 @ SuppressLint ("PrivateResource" )
@@ -65,7 +72,14 @@ public void onBindViewHolder(@NonNull PreferenceViewHolder view) {
6572
6673 mTextView = (TextView ) view .findViewById (R .id .seekbar_value );
6774 mTextView .setTextAlignment (View .TEXT_ALIGNMENT_TEXT_START );
68- SeekBar seekBar = (SeekBar ) view .findViewById (R .id .seekbar );
75+ mSeekBar = (SeekBar ) view .findViewById (R .id .seekbar );
76+ final SeekBar seekBar = mSeekBar ;
77+
78+ if (mTapToSetValueEnabled ) {
79+ mTextView .setClickable (true );
80+ mTextView .setFocusable (true );
81+ mTextView .setOnClickListener (v -> showSetValueDialog ());
82+ }
6983
7084 seekBar .setOnSeekBarChangeListener (new SeekBar .OnSeekBarChangeListener () {
7185
@@ -99,6 +113,49 @@ public void onStopTrackingTouch(SeekBar seekBar) {
99113 updateTextViewWithSuffix ();
100114 }
101115
116+ /**
117+ * Opt-in: makes the value TextView (e.g. "4096 MB") tappable, opening a
118+ * dialog where an exact value can be typed instead of dragged.
119+ */
120+ public void enableTapToSetValue () {
121+ mTapToSetValueEnabled = true ;
122+ }
123+
124+ private void showSetValueDialog () {
125+ Context context = mTextView .getContext ();
126+
127+ final EditText editText = new EditText (context );
128+ editText .setInputType (InputType .TYPE_CLASS_NUMBER );
129+ editText .setText (String .valueOf (getValue ()));
130+ editText .setSelection (editText .getText ().length ());
131+
132+ new AlertDialog .Builder (context )
133+ .setTitle (getTitle ())
134+ .setView (editText )
135+ .setNegativeButton (android .R .string .cancel , null )
136+ .setPositiveButton (android .R .string .ok , (dialog , which ) -> {
137+ String input = editText .getText ().toString ().trim ();
138+ if (input .isEmpty ()) return ;
139+
140+ int newValue ;
141+ try {
142+ newValue = Integer .parseInt (input );
143+ } catch (NumberFormatException e ) {
144+ return ;
145+ }
146+
147+ int max = getMax ();
148+ if (newValue < mMin ) newValue = mMin ;
149+ if (newValue > max ) newValue = max ;
150+
151+ mSeekBar .setProgress (newValue - mMin );
152+ setValue (newValue );
153+ mTextView .setText (String .valueOf (newValue ));
154+ updateTextViewWithSuffix ();
155+ })
156+ .show ();
157+ }
158+
102159 /**
103160 * Set a suffix to be appended on the TextView associated to the value
104161 * @param suffix The suffix to append as a String
@@ -128,4 +185,4 @@ private void updateTextViewWithSuffix(){
128185 mTextView .setText (String .format ("%s%s" , mTextView .getText (), mSuffix ));
129186 }
130187 }
131- }
188+ }
0 commit comments