回答編集履歴

2

機能改善

2016/11/30 09:23

投稿

Kmassa
Kmassa

スコア161

test CHANGED
@@ -84,8 +84,14 @@
84
84
 
85
85
  import android.content.res.TypedArray;
86
86
 
87
+ import android.support.v7.widget.AppCompatEditText;
88
+
87
89
  import android.util.AttributeSet;
88
90
 
91
+ import android.view.View;
92
+
93
+ import android.view.ViewGroup;
94
+
89
95
  import android.widget.NumberPicker;
90
96
 
91
97
 
@@ -152,6 +158,14 @@
152
158
 
153
159
  private void initialize(Context context, AttributeSet attrs) {
154
160
 
161
+ if (this.isInEditMode()) {
162
+
163
+ return;
164
+
165
+ }
166
+
167
+
168
+
155
169
  // レイアウトで指定された値の取得
156
170
 
157
171
  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNumberPicker, 0, 0);
@@ -240,6 +254,38 @@
240
254
 
241
255
 
242
256
 
257
+ // 一旦最大値を設定
258
+
259
+ super.setValue(value_num);
260
+
261
+
262
+
263
+ for (int i = 0; i < getChildCount(); i++) {
264
+
265
+ View view = getChildAt(i);
266
+
267
+ if (view.getClass().equals(AppCompatEditText.class) == true) {
268
+
269
+ // Text部分のサイズを計算
270
+
271
+ int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST);
272
+
273
+ view.measure(expandSpec, expandSpec);
274
+
275
+
276
+
277
+ // Text部分の幅を設定
278
+
279
+ ViewGroup.LayoutParams params = view.getLayoutParams();
280
+
281
+ params.width = view.getMeasuredWidth();
282
+
283
+ }
284
+
285
+ }
286
+
287
+
288
+
243
289
  // 初期表示のindex
244
290
 
245
291
  super.setValue(0);
@@ -260,6 +306,18 @@
260
306
 
261
307
 
262
308
 
309
+ @Override
310
+
311
+ public void setValue(int value) {
312
+
313
+ // スクロール時に使用されているので、ここに変更は加えない
314
+
315
+ super.setValue(value);
316
+
317
+ }
318
+
319
+
320
+
263
321
  public int getDisplayedValue() {
264
322
 
265
323
  // 選択されている値を取得するときは、こちらを呼び出す
@@ -274,7 +332,9 @@
274
332
 
275
333
  @Override
276
334
 
277
- public void setValue(int value) {
335
+ public void setDisplayedValue(int value) {
336
+
337
+ // プログラム中から表示値の設定をするときは、こちらを呼び出す
278
338
 
279
339
  int pos = 0;
280
340
 

1

カスタムNumberPickerのサンプル追加

2016/11/30 09:23

投稿

Kmassa
Kmassa

スコア161

test CHANGED
@@ -31,3 +31,359 @@
31
31
 
32
32
 
33
33
  もしくは、Source directoryにAndroidComponentLibrary-master\ComponentLibraryを指定してください。
34
+
35
+
36
+
37
+ -追記-
38
+
39
+ カスタムNumberPickerの作り方
40
+
41
+
42
+
43
+ まず、res/valuesにxmlファイルを追加します。
44
+
45
+ ファイル名は「attr.xml」などとします。
46
+
47
+ これにより、レイアウトファイルで指定するパラメータを定義します。
48
+
49
+ ```xml
50
+
51
+ <?xml version="1.0" encoding="utf-8"?>
52
+
53
+ <resources>
54
+
55
+ <declare-styleable name="CustomNumberPicker">
56
+
57
+ <attr name="step" format="integer" />
58
+
59
+ <attr name="min" format="integer" />
60
+
61
+ <attr name="max" format="integer" />
62
+
63
+ </declare-styleable>
64
+
65
+ </resources>
66
+
67
+ ```
68
+
69
+
70
+
71
+ 続いてJava Classを追加します。
72
+
73
+ 名前はxmlで指定したものと同じ「CustomNumberPicker」で、
74
+
75
+ SuperclassとしてNumberPickerを指定します。
76
+
77
+ ```Java
78
+
79
+ package xxx;
80
+
81
+
82
+
83
+ import android.content.Context;
84
+
85
+ import android.content.res.TypedArray;
86
+
87
+ import android.util.AttributeSet;
88
+
89
+ import android.widget.NumberPicker;
90
+
91
+
92
+
93
+ /**
94
+
95
+ * Created by massa on 2016/11/15.
96
+
97
+ */
98
+
99
+
100
+
101
+ public class CustomNumberPicker extends NumberPicker {
102
+
103
+
104
+
105
+ // 表示用の値のリスト
106
+
107
+ private String [] mValueSet;
108
+
109
+
110
+
111
+ // 最大値・最小値
112
+
113
+ private int mMaxValue;
114
+
115
+ private int mMinValue;
116
+
117
+
118
+
119
+ // 刻み幅
120
+
121
+ private int mStep;
122
+
123
+
124
+
125
+ public CustomNumberPicker(Context context) {
126
+
127
+ super(context);
128
+
129
+ }
130
+
131
+
132
+
133
+ public CustomNumberPicker(Context context, AttributeSet attrs) {
134
+
135
+ super(context, attrs);
136
+
137
+ initialize(context, attrs);
138
+
139
+ }
140
+
141
+
142
+
143
+ public CustomNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
144
+
145
+ super(context, attrs, defStyleAttr);
146
+
147
+ initialize(context, attrs);
148
+
149
+ }
150
+
151
+
152
+
153
+ private void initialize(Context context, AttributeSet attrs) {
154
+
155
+ // レイアウトで指定された値の取得
156
+
157
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNumberPicker, 0, 0);
158
+
159
+ try {
160
+
161
+ mStep = typedArray.getInteger(R.styleable.CustomNumberPicker_step, 1);
162
+
163
+ mMinValue = typedArray.getInteger(R.styleable.CustomNumberPicker_min, 0);
164
+
165
+ mMaxValue = typedArray.getInteger(R.styleable.CustomNumberPicker_max, mMinValue);
166
+
167
+ }
168
+
169
+ finally {
170
+
171
+ typedArray.recycle();
172
+
173
+ }
174
+
175
+
176
+
177
+ setValues();
178
+
179
+ }
180
+
181
+
182
+
183
+ private void setValues() {
184
+
185
+ int value_num = 0;
186
+
187
+
188
+
189
+ // minとmaxが逆だったら入れ替える
190
+
191
+ if (mMinValue > mMaxValue) {
192
+
193
+ int temp = mMinValue;
194
+
195
+ mMinValue = mMaxValue;
196
+
197
+ mMaxValue = temp;
198
+
199
+ }
200
+
201
+
202
+
203
+ // min ~ maxに値がいくつ入るか算出
204
+
205
+ value_num = (mMaxValue - mMinValue + mStep - 1) / mStep;
206
+
207
+
208
+
209
+ mValueSet = new String[value_num + 1];
210
+
211
+
212
+
213
+ // 表示値のリストを作る
214
+
215
+ for (int i = 0; i < value_num; i++) {
216
+
217
+ mValueSet[i] = String.valueOf(mMinValue + mStep * i);
218
+
219
+ }
220
+
221
+ mValueSet[value_num] = String.valueOf(mMaxValue);
222
+
223
+
224
+
225
+ // 表示値の数が変わるので、一旦初期化
226
+
227
+ super.setMaxValue(0);
228
+
229
+
230
+
231
+ setDisplayedValues(mValueSet);
232
+
233
+
234
+
235
+ // 本来のValueはindexとして使用する
236
+
237
+ super.setMinValue(0);
238
+
239
+ super.setMaxValue(value_num);
240
+
241
+
242
+
243
+ // 初期表示のindex
244
+
245
+ super.setValue(0);
246
+
247
+ }
248
+
249
+
250
+
251
+ @Override
252
+
253
+ public int getValue() {
254
+
255
+ // setDisplayedValuesでも使用しているので、ここに変更は加えない
256
+
257
+ return super.getValue();
258
+
259
+ }
260
+
261
+
262
+
263
+ public int getDisplayedValue() {
264
+
265
+ // 選択されている値を取得するときは、こちらを呼び出す
266
+
267
+ int pos = super.getValue();
268
+
269
+ return Integer.parseInt(mValueSet[pos]);
270
+
271
+ }
272
+
273
+
274
+
275
+ @Override
276
+
277
+ public void setValue(int value) {
278
+
279
+ int pos = 0;
280
+
281
+ while (value > Integer.parseInt(mValueSet[pos])) {
282
+
283
+ pos++;
284
+
285
+ }
286
+
287
+ super.setValue(pos);
288
+
289
+ }
290
+
291
+
292
+
293
+ @Override
294
+
295
+ public int getMinValue() {
296
+
297
+ return mMinValue;
298
+
299
+ }
300
+
301
+
302
+
303
+ @Override
304
+
305
+ public void setMinValue(int minValue) {
306
+
307
+ mMinValue = minValue;
308
+
309
+ setValues();
310
+
311
+ }
312
+
313
+
314
+
315
+ @Override
316
+
317
+ public int getMaxValue() {
318
+
319
+ return mMaxValue;
320
+
321
+ }
322
+
323
+
324
+
325
+ @Override
326
+
327
+ public void setMaxValue(int maxValue) {
328
+
329
+ mMaxValue = maxValue;
330
+
331
+ setValues();
332
+
333
+ }
334
+
335
+ }
336
+
337
+ ```
338
+
339
+
340
+
341
+ 後は、レイアウトファイルから以下のように使用できると思います。
342
+
343
+ ```xml
344
+
345
+ <xxx.CustomNumberPicker
346
+
347
+ xmlns:custom="http://schemas.android.com/apk/res-auto"
348
+
349
+ android:layout_width="wrap_content"
350
+
351
+ android:layout_height="wrap_content"
352
+
353
+ custom:step="5"
354
+
355
+ custom:min="10"
356
+
357
+ custom:max="100"
358
+
359
+ android:id="@+id/numberPicker"/>
360
+
361
+ ```
362
+
363
+
364
+
365
+ 選択されている値は、以下のように取得できます。
366
+
367
+ ```Java
368
+
369
+ CustomNumberPicker customNumberPicker = (CustomNumberPicker)findViewById(R.id.numberPicker);
370
+
371
+
372
+
373
+ int value = customNumberPicker.getDisplayedValue();
374
+
375
+ ```
376
+
377
+ 当初、getValue()をオーバーライドしてみたのですが、
378
+
379
+ setDisplayedValuesの中から呼び出されているようで、表示される値がおかしくなってしまいました。
380
+
381
+ なので、getValue()はいじらず、getDisplayedValue()というメソッドを追加しています。
382
+
383
+
384
+
385
+ パッケージ名はxxxとしているので、適宜変更してください。
386
+
387
+ 色々なケースを試せてないので、問題あればご指摘ください。
388
+
389
+