/[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 19 - (show annotations) (download)
Sun Dec 11 12:56:26 2011 UTC (12 years, 4 months ago) by zoff99
File size: 8638 byte(s)
new Java clases for numberpicker(s)
1 /*
2 *
3 * Enhanced by Zoff (c) 2011
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.InputType;
44 import android.util.AttributeSet;
45 import android.view.Gravity;
46 import android.view.KeyEvent;
47 import android.view.MotionEvent;
48 import android.view.View;
49 import android.widget.Button;
50 import android.widget.EditText;
51 import android.widget.LinearLayout;
52
53 /**
54 * A simple layout group that provides a numeric text area with two buttons to
55 * increment or decrement the value in the text area. Holding either button
56 * will auto increment the value up or down appropriately.
57 *
58 * @author Jeffrey F. Cole
59 *
60 */
61 public class NumberPicker extends LinearLayout
62 {
63
64 private final long REPEAT_DELAY = 50;
65
66 private final int ELEMENT_HEIGHT = 120;
67 private final int ELEMENT_WIDTH = 70;
68
69 private final int MINIMUM = 0;
70 private final int MAXIMUM = 9;
71
72 private int mMaxValue = MAXIMUM;
73 private int mMinValue = MINIMUM;
74
75 public Integer value;
76
77 Button decrement;
78 Button increment;
79 public EditText valueText;
80
81 private Handler repeatUpdateHandler = new Handler();
82
83 private boolean autoIncrement = false;
84 private boolean autoDecrement = false;
85
86 /**
87 * This little guy handles the auto part of the auto incrementing feature.
88 * In doing so it instantiates itself. There has to be a pattern name for
89 * that...
90 *
91 * @author Jeffrey F. Cole
92 *
93 */
94 class RepetetiveUpdater implements Runnable
95 {
96 public void run()
97 {
98 if (autoIncrement)
99 {
100 increment();
101 repeatUpdateHandler.postDelayed(new RepetetiveUpdater(), REPEAT_DELAY);
102 }
103 else if (autoDecrement)
104 {
105 decrement();
106 repeatUpdateHandler.postDelayed(new RepetetiveUpdater(), REPEAT_DELAY);
107 }
108 }
109 }
110
111 public NumberPicker(Context context, AttributeSet attributeSet)
112 {
113 super(context, attributeSet);
114
115 int nW = attributeSet.getAttributeIntValue(null, "nwidth", android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
116 int nH = attributeSet.getAttributeIntValue(null, "nheight", android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
117 mMinValue = attributeSet.getAttributeIntValue(null, "minValue", mMinValue);
118 mMaxValue = attributeSet.getAttributeIntValue(null, "maxValue", mMaxValue);
119
120 this.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
121 LayoutParams elementParams = new LinearLayout.LayoutParams(nW, nH);
122
123 // init the individual elements
124 initDecrementButton(context);
125 initValueEditText(context);
126 initIncrementButton(context);
127
128 // Can be configured to be vertical or horizontal
129 // Thanks for the help, LinearLayout!
130 if (getOrientation() == VERTICAL)
131 {
132 addView(increment, elementParams);
133 addView(valueText, elementParams);
134 addView(decrement, elementParams);
135 }
136 else
137 {
138 addView(decrement, elementParams);
139 addView(valueText, elementParams);
140 addView(increment, elementParams);
141 }
142 }
143
144 private void initIncrementButton(Context context)
145 {
146 increment = new Button(context);
147 increment.setTextSize(20);
148 increment.setText("+");
149
150 // Increment once for a click
151 increment.setOnClickListener(new View.OnClickListener()
152 {
153 public void onClick(View v)
154 {
155 increment();
156 }
157 });
158
159 // Auto increment for a long click
160 increment.setOnLongClickListener(new View.OnLongClickListener()
161 {
162 public boolean onLongClick(View arg0)
163 {
164 autoIncrement = true;
165 repeatUpdateHandler.post(new RepetetiveUpdater());
166 return false;
167 }
168 });
169
170 // When the button is released, if we're auto incrementing, stop
171 increment.setOnTouchListener(new View.OnTouchListener()
172 {
173 public boolean onTouch(View v, MotionEvent event)
174 {
175 if (event.getAction() == MotionEvent.ACTION_UP && autoIncrement)
176 {
177 autoIncrement = false;
178 }
179 return false;
180 }
181 });
182 }
183
184 private void initValueEditText(Context context)
185 {
186
187 value = new Integer(0);
188
189 valueText = new EditText(context);
190 valueText.setTextSize(20);
191
192 // Since we're a number that gets affected by the button, we need to be
193 // ready to change the numeric value with a simple ++/--, so whenever
194 // the value is changed with a keyboard, convert that text value to a
195 // number. We can set the text area to only allow numeric input, but
196 // even so, a carriage return can get hacked through. To prevent this
197 // little quirk from causing a crash, store the value of the internal
198 // number before attempting to parse the changed value in the text area
199 // so we can revert to that in case the text change causes an invalid
200 // number
201 valueText.setOnKeyListener(new View.OnKeyListener()
202 {
203 public boolean onKey(View v, int arg1, KeyEvent event)
204 {
205 int backupValue = value;
206 try
207 {
208 value = Integer.parseInt(((EditText) v).getText().toString());
209 }
210 catch (NumberFormatException nfe)
211 {
212 value = backupValue;
213 }
214 return false;
215 }
216 });
217
218 // Highlight the number when we get focus
219 valueText.setOnFocusChangeListener(new View.OnFocusChangeListener()
220 {
221 public void onFocusChange(View v, boolean hasFocus)
222 {
223 if (hasFocus)
224 {
225 ((EditText) v).selectAll();
226 }
227 }
228 });
229 valueText.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
230 valueText.setText(value.toString());
231 valueText.setInputType(InputType.TYPE_CLASS_NUMBER);
232 }
233
234 private void initDecrementButton(Context context)
235 {
236 decrement = new Button(context);
237 decrement.setTextSize(20);
238 decrement.setText("-");
239
240 // Decrement once for a click
241 decrement.setOnClickListener(new View.OnClickListener()
242 {
243 public void onClick(View v)
244 {
245 decrement();
246 }
247 });
248
249 // Auto Decrement for a long click
250 decrement.setOnLongClickListener(new View.OnLongClickListener()
251 {
252 public boolean onLongClick(View arg0)
253 {
254 autoDecrement = true;
255 repeatUpdateHandler.post(new RepetetiveUpdater());
256 return false;
257 }
258 });
259
260 // When the button is released, if we're auto decrementing, stop
261 decrement.setOnTouchListener(new View.OnTouchListener()
262 {
263 public boolean onTouch(View v, MotionEvent event)
264 {
265 if (event.getAction() == MotionEvent.ACTION_UP && autoDecrement)
266 {
267 autoDecrement = false;
268 }
269 return false;
270 }
271 });
272 }
273
274 public void increment()
275 {
276 if (value < mMaxValue)
277 {
278 value = value + 1;
279 valueText.setText(value.toString());
280 }
281 }
282
283 public void decrement()
284 {
285 if (value > mMinValue)
286 {
287 value = value - 1;
288 valueText.setText(value.toString());
289 }
290 }
291
292 public int getValue()
293 {
294 return value;
295 }
296
297 public void setValue(int value)
298 {
299 if (value > mMaxValue) value = mMaxValue;
300 if (value >= 0)
301 {
302 this.value = value;
303 valueText.setText(this.value.toString());
304 }
305 }
306
307 }

   
Visit the ZANavi Wiki