/[zanavi_public1]/navit/navit/android/src/net/technologichron/manacalc/NumberPicker.java
ZANavi

Contents of /navit/navit/android/src/net/technologichron/manacalc/NumberPicker.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (show annotations) (download)
Sun Jun 17 08:12:47 2012 UTC (11 years, 9 months ago) by zoff99
File size: 9354 byte(s)
lots of new stuff and fixes
1 /**
2 *
3 * Enhanced by Zoff (c) 2011 - 2012
4 * zoff@zanavi.cc
5 *
6 */
7
8 /**
9 * Copyright (c) 2010, Jeffrey F. Cole
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * Redistributions of source code must retain the above copyright notice, this
16 * list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * Neither the name of the technologichron.net nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 package net.technologichron.manacalc;
40
41 import android.content.Context;
42 import android.os.Handler;
43 import android.text.Editable;
44 import android.text.InputType;
45 import android.text.TextWatcher;
46 import android.util.AttributeSet;
47 import android.view.Gravity;
48 import android.view.KeyEvent;
49 import android.view.MotionEvent;
50 import android.view.View;
51 import android.widget.Button;
52 import android.widget.EditText;
53 import android.widget.LinearLayout;
54
55 /**
56 * A simple layout group that provides a numeric text area with two buttons to
57 * increment or decrement the value in the text area. Holding either button
58 * will auto increment the value up or down appropriately.
59 *
60 * @author Jeffrey F. Cole
61 *
62 */
63 public class NumberPicker extends LinearLayout
64 {
65
66 private final long REPEAT_DELAY = 50;
67
68 private final int ELEMENT_HEIGHT = 120;
69 private final int ELEMENT_WIDTH = 70;
70
71 private final int MINIMUM = 0;
72 private final int MAXIMUM = 9;
73
74 private int mMaxValue = MAXIMUM;
75 private int mMinValue = MINIMUM;
76
77 public Integer value;
78
79 Button decrement;
80 Button increment;
81 public EditText valueText;
82
83 private Handler repeatUpdateHandler = new Handler();
84
85 private boolean autoIncrement = false;
86 private boolean autoDecrement = false;
87
88 /**
89 * This little guy handles the auto part of the auto incrementing feature.
90 * In doing so it instantiates itself. There has to be a pattern name for
91 * that...
92 *
93 * @author Jeffrey F. Cole
94 *
95 */
96 class RepetetiveUpdater implements Runnable
97 {
98 public void run()
99 {
100 if (autoIncrement)
101 {
102 increment();
103 repeatUpdateHandler.postDelayed(new RepetetiveUpdater(), REPEAT_DELAY);
104 }
105 else if (autoDecrement)
106 {
107 decrement();
108 repeatUpdateHandler.postDelayed(new RepetetiveUpdater(), REPEAT_DELAY);
109 }
110 }
111 }
112
113 public NumberPicker(Context context, AttributeSet attributeSet)
114 {
115 super(context, attributeSet);
116
117 int nW = attributeSet.getAttributeIntValue(null, "nwidth", android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
118 int nH = attributeSet.getAttributeIntValue(null, "nheight", android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
119 mMinValue = attributeSet.getAttributeIntValue(null, "minValue", mMinValue);
120 mMaxValue = attributeSet.getAttributeIntValue(null, "maxValue", mMaxValue);
121
122 this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
123 LayoutParams elementParams = new LinearLayout.LayoutParams(nW, nH);
124
125 // init the individual elements
126 initDecrementButton(context);
127 initValueEditText(context);
128 initIncrementButton(context);
129
130 // Can be configured to be vertical or horizontal
131 // Thanks for the help, LinearLayout!
132 if (getOrientation() == VERTICAL)
133 {
134 addView(increment, elementParams);
135 addView(valueText, elementParams);
136 addView(decrement, elementParams);
137 }
138 else
139 {
140 addView(decrement, elementParams);
141 addView(valueText, elementParams);
142 addView(increment, elementParams);
143 }
144 }
145
146 private void initIncrementButton(Context context)
147 {
148 increment = new Button(context);
149 increment.setTextSize(20);
150 increment.setText("+");
151
152 // Increment once for a click
153 increment.setOnClickListener(new View.OnClickListener()
154 {
155 public void onClick(View v)
156 {
157 increment();
158 }
159 });
160
161 // Auto increment for a long click
162 increment.setOnLongClickListener(new View.OnLongClickListener()
163 {
164 public boolean onLongClick(View arg0)
165 {
166 autoIncrement = true;
167 repeatUpdateHandler.post(new RepetetiveUpdater());
168 return false;
169 }
170 });
171
172 // When the button is released, if we're auto incrementing, stop
173 increment.setOnTouchListener(new View.OnTouchListener()
174 {
175 public boolean onTouch(View v, MotionEvent event)
176 {
177 if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement)
178 {
179 autoIncrement = false;
180 }
181 return false;
182 }
183 });
184 }
185
186 private void initValueEditText(Context context)
187 {
188
189 value = new Integer(0);
190
191 valueText = new EditText(context);
192 valueText.setTextSize(20);
193
194 // Since we're a number that gets affected by the button, we need to be
195 // ready to change the numeric value with a simple ++/--, so whenever
196 // the value is changed with a keyboard, convert that text value to a
197 // number. We can set the text area to only allow numeric input, but
198 // even so, a carriage return can get hacked through. To prevent this
199 // little quirk from causing a crash, store the value of the internal
200 // number before attempting to parse the changed value in the text area
201 // so we can revert to that in case the text change causes an invalid
202 // number
203 valueText.setOnKeyListener(new View.OnKeyListener()
204 {
205 public boolean onKey(View v, int arg1, KeyEvent event)
206 {
207 //System.out.println("xx222222222222");
208 int backupValue = value;
209 try
210 {
211 value = Integer.parseInt(((EditText) v).getText().toString());
212 }
213 catch (NumberFormatException nfe)
214 {
215 value = backupValue;
216 }
217 return false;
218 }
219 });
220
221 valueText.addTextChangedListener(new TextWatcher()
222 {
223 @Override
224 public void afterTextChanged(Editable s)
225 {
226 //System.out.println("xxxxxxxx111");
227 int backupValue = value;
228 try
229 {
230 value = Integer.parseInt(valueText.getText().toString());
231 }
232 catch (NumberFormatException nfe)
233 {
234 value = backupValue;
235 }
236 }
237
238 @Override
239 public void beforeTextChanged(CharSequence s, int start, int count, int after)
240 {
241 }
242
243 @Override
244 public void onTextChanged(CharSequence s, int start, int before, int count)
245 {
246 }
247 });
248
249 // Highlight the number when we get focus
250 valueText.setOnFocusChangeListener(new View.OnFocusChangeListener()
251 {
252 public void onFocusChange(View v, boolean hasFocus)
253 {
254 if (hasFocus)
255 {
256 ((EditText) v).selectAll();
257 }
258 }
259 });
260 valueText.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
261 valueText.setText(value.toString());
262 valueText.setInputType(InputType.TYPE_CLASS_NUMBER);
263 }
264
265 private void initDecrementButton(Context context)
266 {
267 decrement = new Button(context);
268 decrement.setTextSize(20);
269 decrement.setText("-");
270
271 // Decrement once for a click
272 decrement.setOnClickListener(new View.OnClickListener()
273 {
274 public void onClick(View v)
275 {
276 decrement();
277 }
278 });
279
280 // Auto Decrement for a long click
281 decrement.setOnLongClickListener(new View.OnLongClickListener()
282 {
283 public boolean onLongClick(View arg0)
284 {
285 autoDecrement = true;
286 repeatUpdateHandler.post(new RepetetiveUpdater());
287 return false;
288 }
289 });
290
291 // When the button is released, if we're auto decrementing, stop
292 decrement.setOnTouchListener(new View.OnTouchListener()
293 {
294 public boolean onTouch(View v, MotionEvent event)
295 {
296 if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement)
297 {
298 autoDecrement = false;
299 }
300 return false;
301 }
302 });
303 }
304
305 public void increment()
306 {
307 if (value < mMaxValue)
308 {
309 value = value + 1;
310 valueText.setText(value.toString());
311 }
312 }
313
314 public void decrement()
315 {
316 if (value > mMinValue)
317 {
318 value = value - 1;
319 valueText.setText(value.toString());
320 }
321 }
322
323 public int getValue()
324 {
325 return value;
326 }
327
328 public void setValue(int value)
329 {
330 if (value > mMaxValue) value = mMaxValue;
331 if (value >= 0)
332 {
333 this.value = value;
334 valueText.setText(this.value.toString());
335 }
336 }
337
338 }

   
Visit the ZANavi Wiki