1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.preference; 18 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.content.Context; 21 import android.content.res.TypedArray; 22 import android.os.Build; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.util.AttributeSet; 26 import android.view.KeyEvent; 27 import android.view.View; 28 import android.widget.SeekBar; 29 import android.widget.SeekBar.OnSeekBarChangeListener; 30 31 /** 32 * @hide 33 * 34 * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a> 35 * <a href="{@docRoot}reference/androidx/preference/package-summary.html"> 36 * Preference Library</a> for consistent behavior across all devices. For more information on 37 * using the AndroidX Preference Library see 38 * <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>. 39 */ 40 @Deprecated 41 public class SeekBarPreference extends Preference 42 implements OnSeekBarChangeListener { 43 44 private int mProgress; 45 private int mMax; 46 private boolean mTrackingTouch; 47 SeekBarPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)48 public SeekBarPreference( 49 Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 50 super(context, attrs, defStyleAttr, defStyleRes); 51 52 TypedArray a = context.obtainStyledAttributes( 53 attrs, com.android.internal.R.styleable.ProgressBar, defStyleAttr, defStyleRes); 54 setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax)); 55 a.recycle(); 56 57 a = context.obtainStyledAttributes(attrs, 58 com.android.internal.R.styleable.SeekBarPreference, defStyleAttr, defStyleRes); 59 final int layoutResId = a.getResourceId( 60 com.android.internal.R.styleable.SeekBarPreference_layout, 61 com.android.internal.R.layout.preference_widget_seekbar); 62 a.recycle(); 63 64 setLayoutResource(layoutResId); 65 } 66 67 @UnsupportedAppUsage SeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr)68 public SeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) { 69 this(context, attrs, defStyleAttr, 0); 70 } 71 72 @UnsupportedAppUsage SeekBarPreference(Context context, AttributeSet attrs)73 public SeekBarPreference(Context context, AttributeSet attrs) { 74 this(context, attrs, com.android.internal.R.attr.seekBarPreferenceStyle); 75 } 76 77 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) SeekBarPreference(Context context)78 public SeekBarPreference(Context context) { 79 this(context, null); 80 } 81 82 @Override onBindView(View view)83 protected void onBindView(View view) { 84 super.onBindView(view); 85 SeekBar seekBar = (SeekBar) view.findViewById( 86 com.android.internal.R.id.seekbar); 87 seekBar.setOnSeekBarChangeListener(this); 88 seekBar.setMax(mMax); 89 seekBar.setProgress(mProgress); 90 seekBar.setEnabled(isEnabled()); 91 } 92 93 @Override onSetInitialValue(boolean restoreValue, Object defaultValue)94 protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { 95 setProgress(restoreValue ? getPersistedInt(mProgress) 96 : (Integer) defaultValue); 97 } 98 99 @Override onGetDefaultValue(TypedArray a, int index)100 protected Object onGetDefaultValue(TypedArray a, int index) { 101 return a.getInt(index, 0); 102 } 103 104 @Override onKey(View v, int keyCode, KeyEvent event)105 public boolean onKey(View v, int keyCode, KeyEvent event) { 106 if (event.getAction() != KeyEvent.ACTION_DOWN) { 107 return false; 108 } 109 110 SeekBar seekBar = (SeekBar) v.findViewById(com.android.internal.R.id.seekbar); 111 if (seekBar == null) { 112 return false; 113 } 114 return seekBar.onKeyDown(keyCode, event); 115 } 116 setMax(int max)117 public void setMax(int max) { 118 if (max != mMax) { 119 mMax = max; 120 notifyChanged(); 121 } 122 } 123 setProgress(int progress)124 public void setProgress(int progress) { 125 setProgress(progress, true); 126 } 127 setProgress(int progress, boolean notifyChanged)128 private void setProgress(int progress, boolean notifyChanged) { 129 if (progress > mMax) { 130 progress = mMax; 131 } 132 if (progress < 0) { 133 progress = 0; 134 } 135 if (progress != mProgress) { 136 mProgress = progress; 137 persistInt(progress); 138 if (notifyChanged) { 139 notifyChanged(); 140 } 141 } 142 } 143 getProgress()144 public int getProgress() { 145 return mProgress; 146 } 147 148 /** 149 * Persist the seekBar's progress value if callChangeListener 150 * returns true, otherwise set the seekBar's progress to the stored value 151 */ syncProgress(SeekBar seekBar)152 void syncProgress(SeekBar seekBar) { 153 int progress = seekBar.getProgress(); 154 if (progress != mProgress) { 155 if (callChangeListener(progress)) { 156 setProgress(progress, false); 157 } else { 158 seekBar.setProgress(mProgress); 159 } 160 } 161 } 162 163 @Override onProgressChanged( SeekBar seekBar, int progress, boolean fromUser)164 public void onProgressChanged( 165 SeekBar seekBar, int progress, boolean fromUser) { 166 if (fromUser && !mTrackingTouch) { 167 syncProgress(seekBar); 168 } 169 } 170 171 @Override onStartTrackingTouch(SeekBar seekBar)172 public void onStartTrackingTouch(SeekBar seekBar) { 173 mTrackingTouch = true; 174 } 175 176 @Override onStopTrackingTouch(SeekBar seekBar)177 public void onStopTrackingTouch(SeekBar seekBar) { 178 mTrackingTouch = false; 179 if (seekBar.getProgress() != mProgress) { 180 syncProgress(seekBar); 181 } 182 } 183 184 @Override onSaveInstanceState()185 protected Parcelable onSaveInstanceState() { 186 /* 187 * Suppose a client uses this preference type without persisting. We 188 * must save the instance state so it is able to, for example, survive 189 * orientation changes. 190 */ 191 192 final Parcelable superState = super.onSaveInstanceState(); 193 if (isPersistent()) { 194 // No need to save instance state since it's persistent 195 return superState; 196 } 197 198 // Save the instance state 199 final SavedState myState = new SavedState(superState); 200 myState.progress = mProgress; 201 myState.max = mMax; 202 return myState; 203 } 204 205 @Override onRestoreInstanceState(Parcelable state)206 protected void onRestoreInstanceState(Parcelable state) { 207 if (!state.getClass().equals(SavedState.class)) { 208 // Didn't save state for us in onSaveInstanceState 209 super.onRestoreInstanceState(state); 210 return; 211 } 212 213 // Restore the instance state 214 SavedState myState = (SavedState) state; 215 super.onRestoreInstanceState(myState.getSuperState()); 216 mProgress = myState.progress; 217 mMax = myState.max; 218 notifyChanged(); 219 } 220 221 /** 222 * SavedState, a subclass of {@link BaseSavedState}, will store the state 223 * of MyPreference, a subclass of Preference. 224 * <p> 225 * It is important to always call through to super methods. 226 */ 227 private static class SavedState extends BaseSavedState { 228 int progress; 229 int max; 230 SavedState(Parcel source)231 public SavedState(Parcel source) { 232 super(source); 233 234 // Restore the click counter 235 progress = source.readInt(); 236 max = source.readInt(); 237 } 238 239 @Override writeToParcel(Parcel dest, int flags)240 public void writeToParcel(Parcel dest, int flags) { 241 super.writeToParcel(dest, flags); 242 243 // Save the click counter 244 dest.writeInt(progress); 245 dest.writeInt(max); 246 } 247 SavedState(Parcelable superState)248 public SavedState(Parcelable superState) { 249 super(superState); 250 } 251 252 @SuppressWarnings("unused") 253 public static final @android.annotation.NonNull Parcelable.Creator<SavedState> CREATOR = 254 new Parcelable.Creator<SavedState>() { 255 public SavedState createFromParcel(Parcel in) { 256 return new SavedState(in); 257 } 258 259 public SavedState[] newArray(int size) { 260 return new SavedState[size]; 261 } 262 }; 263 } 264 } 265