comparison XposedLibrary/src/de/robv/android/xposed/library/ui/ValueSeekBarPreference.java @ 0:3da8a7a621cd

Initial commit
author Brad Greco <brad@bgreco.net>
date Mon, 20 Jan 2014 22:56:13 -0600
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3da8a7a621cd
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 de.robv.android.xposed.library.ui;
18
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.preference.Preference;
24 import android.util.AttributeSet;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.SeekBar;
29 import android.widget.SeekBar.OnSeekBarChangeListener;
30 import android.widget.TextView;
31 import de.robv.android.xposed.library.R;
32
33 public class ValueSeekBarPreference extends Preference implements OnSeekBarChangeListener {
34
35 private int mProgress;
36 private int mStep;
37 private int mMin;
38 private int mMax;
39 private String valueDisplayFormat;
40 private boolean mTrackingTouch;
41 private TextView tvValue;
42
43 public ValueSeekBarPreference(
44 Context context, AttributeSet attrs, int defStyle) {
45 super(context, attrs, defStyle);
46
47 if (attrs != null) {
48 setStep(attrs.getAttributeIntValue(null, "step", 1));
49 setMin(attrs.getAttributeIntValue(null, "min", 0));
50 setMax(attrs.getAttributeIntValue(null, "max", 100));
51 valueDisplayFormat = attrs.getAttributeValue(null, "displayFormat");
52 if (valueDisplayFormat == null)
53 valueDisplayFormat = "%d";
54 }
55 }
56
57 public ValueSeekBarPreference(Context context, AttributeSet attrs) {
58 this(context, attrs, android.R.attr.preferenceStyle);
59 }
60
61 public ValueSeekBarPreference(Context context) {
62 this(context, null);
63 }
64
65 @Override
66 protected View onCreateView(ViewGroup parent) {
67 ViewGroup originalView = (ViewGroup) super.onCreateView(parent);
68
69 final LayoutInflater layoutInflater =
70 (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
71
72 ViewGroup newlayout = (ViewGroup) layoutInflater.inflate(R.layout.preference_valueseekbar_extension, null);
73 newlayout.addView(originalView, 0);
74
75 tvValue = (TextView) newlayout.findViewById(R.id.valueseekbar_preference_value);
76
77 return newlayout;
78 }
79
80 @Override
81 protected void onBindView(View view) {
82 super.onBindView(view);
83 SeekBar seekBar = (SeekBar) view.findViewById(R.id.valueseekbar_preference_seekbar);
84 seekBar.setOnSeekBarChangeListener(this);
85 seekBar.setMax((mMax - mMin) / mStep);
86 seekBar.setProgress((mProgress - mMin) / mStep);
87 tvValue.setText(String.format(valueDisplayFormat, mProgress));
88 seekBar.setEnabled(isEnabled());
89 }
90
91 @Override
92 protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
93 setProgress(restoreValue ? getPersistedInt(mProgress)
94 : (Integer) defaultValue);
95 }
96
97 @Override
98 protected Object onGetDefaultValue(TypedArray a, int index) {
99 return a.getInt(index, 0);
100 }
101
102 public void setStep(int step) {
103 if (step != mStep) {
104 mStep = step;
105 notifyChanged();
106 }
107 }
108
109 public void setMin(int min) {
110 if (min != mMin) {
111 mMin = min;
112 notifyChanged();
113 }
114 }
115
116 public void setMax(int max) {
117 if (max != mMax) {
118 mMax = max;
119 notifyChanged();
120 }
121 }
122
123 public void setProgress(int progress) {
124 setProgress(progress, true);
125 }
126
127 private void setProgress(int progress, boolean notifyChanged) {
128 if (progress > mMax) {
129 progress = mMax;
130 }
131 if (progress < mMin) {
132 progress = mMin;
133 }
134 if (progress != mProgress) {
135 mProgress = progress;
136 persistInt(progress);
137 if (notifyChanged) {
138 notifyChanged();
139 }
140 }
141 }
142
143 public int getProgress() {
144 return mProgress;
145 }
146
147 /**
148 * Persist the seekBar's progress value if callChangeListener
149 * returns true, otherwise set the seekBar's progress to the stored value
150 */
151 void syncProgress(SeekBar seekBar) {
152 int progress = seekBar.getProgress() * mStep + mMin;
153 if (progress != mProgress) {
154 if (callChangeListener(progress)) {
155 setProgress(progress, false);
156 } else {
157 seekBar.setProgress((mProgress - mMin) / mStep);
158 }
159 }
160 }
161
162 @Override
163 public void onProgressChanged(
164 SeekBar seekBar, int progress, boolean fromUser) {
165 if (fromUser && !mTrackingTouch) {
166 syncProgress(seekBar);
167 }
168 tvValue.setText(String.format(valueDisplayFormat, progress * mStep + mMin));
169 }
170
171 @Override
172 public void onStartTrackingTouch(SeekBar seekBar) {
173 mTrackingTouch = true;
174 }
175
176 @Override
177 public void onStopTrackingTouch(SeekBar seekBar) {
178 mTrackingTouch = false;
179 if (seekBar.getProgress() * mStep + mMin != mProgress) {
180 syncProgress(seekBar);
181 }
182 }
183
184 @Override
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.step = mStep;
202 myState.min = mMin;
203 myState.max = mMax;
204 return myState;
205 }
206
207 @Override
208 protected void onRestoreInstanceState(Parcelable state) {
209 if (!state.getClass().equals(SavedState.class)) {
210 // Didn't save state for us in onSaveInstanceState
211 super.onRestoreInstanceState(state);
212 return;
213 }
214
215 // Restore the instance state
216 SavedState myState = (SavedState) state;
217 super.onRestoreInstanceState(myState.getSuperState());
218 mProgress = myState.progress;
219 mStep = myState.step;
220 mMin = myState.min;
221 mMax = myState.max;
222 notifyChanged();
223 }
224
225 /**
226 * SavedState, a subclass of {@link BaseSavedState}, will store the state
227 * of MyPreference, a subclass of Preference.
228 * <p>
229 * It is important to always call through to super methods.
230 */
231 private static class SavedState extends BaseSavedState {
232 int progress;
233 int step;
234 int min;
235 int max;
236
237 public SavedState(Parcel source) {
238 super(source);
239
240 // Restore the click counter
241 progress = source.readInt();
242 step = source.readInt();
243 min = source.readInt();
244 max = source.readInt();
245 }
246
247 @Override
248 public void writeToParcel(Parcel dest, int flags) {
249 super.writeToParcel(dest, flags);
250
251 dest.writeInt(progress);
252 dest.writeInt(step);
253 dest.writeInt(min);
254 dest.writeInt(max);
255 }
256
257 public SavedState(Parcelable superState) {
258 super(superState);
259 }
260
261 @SuppressWarnings("unused")
262 public static final Parcelable.Creator<SavedState> CREATOR =
263 new Parcelable.Creator<SavedState>() {
264 public SavedState createFromParcel(Parcel in) {
265 return new SavedState(in);
266 }
267
268 public SavedState[] newArray(int size) {
269 return new SavedState[size];
270 }
271 };
272 }
273 }