29
29
import android .content .res .ColorStateList ;
30
30
import android .content .res .Resources ;
31
31
import android .content .res .TypedArray ;
32
+ import android .graphics .Outline ;
32
33
import android .graphics .RadialGradient ;
33
34
import android .graphics .Rect ;
34
35
import android .graphics .RectF ;
39
40
import android .util .AttributeSet ;
40
41
import android .util .DisplayMetrics ;
41
42
import android .util .SparseArray ;
43
+ import android .view .KeyEvent ;
42
44
import android .view .LayoutInflater ;
43
45
import android .view .MotionEvent ;
44
46
import android .view .View ;
47
+ import android .view .ViewOutlineProvider ;
45
48
import android .view .ViewTreeObserver .OnPreDrawListener ;
46
49
import android .view .accessibility .AccessibilityNodeInfo ;
47
50
import android .widget .TextView ;
@@ -92,6 +95,8 @@ class ClockFaceView extends RadialViewGroup implements OnRotateListener {
92
95
93
96
private final ColorStateList textColor ;
94
97
98
+ private OnEnterKeyPressedListener onEnterKeyPressedListener ;
99
+
95
100
public ClockFaceView (@ NonNull Context context ) {
96
101
this (context , null );
97
102
}
@@ -150,8 +155,18 @@ public boolean onPreDraw() {
150
155
}
151
156
});
152
157
153
- setFocusable (false );
154
158
a .recycle ();
159
+
160
+ setOutlineProvider (
161
+ new ViewOutlineProvider () {
162
+ @ Override
163
+ public void getOutline (View view , Outline outline ) {
164
+ outline .setOval (0 , 0 , view .getWidth (), view .getHeight ());
165
+ }
166
+ });
167
+ setFocusable (true );
168
+ setClipToOutline (true );
169
+
155
170
valueAccessibilityDelegate =
156
171
new AccessibilityDelegateCompat () {
157
172
@ Override
@@ -167,7 +182,7 @@ public void onInitializeAccessibilityNodeInfo(
167
182
CollectionItemInfoCompat .obtain (
168
183
/* rowIndex= */ 0 ,
169
184
/* rowSpan= */ 1 ,
170
- /* columnIndex = */ index ,
185
+ /* columnIndex= */ index ,
171
186
/* columnSpan= */ 1 ,
172
187
/* heading= */ false ,
173
188
/* selected= */ host .isSelected ()));
@@ -375,6 +390,57 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
375
390
super .onMeasure (spec , spec );
376
391
}
377
392
393
+ private int getSelectedIndex () {
394
+ for (int i = 0 ; i < textViewPool .size (); i ++) {
395
+ TextView textView = textViewPool .valueAt (i );
396
+ if (textView .isSelected ()) {
397
+ return (int ) textView .getTag (R .id .material_value_index );
398
+ }
399
+ }
400
+ return -1 ;
401
+ }
402
+
403
+ @ Override
404
+ public boolean onKeyDown (int keyCode , KeyEvent event ) {
405
+ int selectedIndex = getSelectedIndex ();
406
+ if (!isShown () || selectedIndex == -1 ) {
407
+ return super .onKeyDown (keyCode , event );
408
+ }
409
+
410
+ int nextIndex ;
411
+ switch (keyCode ) {
412
+ case KeyEvent .KEYCODE_DPAD_RIGHT :
413
+ case KeyEvent .KEYCODE_DPAD_UP :
414
+ nextIndex = (selectedIndex + 1 ) % values .length ;
415
+ break ;
416
+ case KeyEvent .KEYCODE_DPAD_LEFT :
417
+ case KeyEvent .KEYCODE_DPAD_DOWN :
418
+ nextIndex = (selectedIndex - 1 + values .length ) % values .length ;
419
+ break ;
420
+ case KeyEvent .KEYCODE_ENTER :
421
+ case KeyEvent .KEYCODE_DPAD_CENTER :
422
+ if (onEnterKeyPressedListener != null ) {
423
+ onEnterKeyPressedListener .onEnterKeyPressed ();
424
+ }
425
+ return true ;
426
+ default :
427
+ return super .onKeyDown (keyCode , event );
428
+ }
429
+
430
+ if (nextIndex != selectedIndex ) {
431
+ int level = (nextIndex / INITIAL_CAPACITY ) + LEVEL_1 ;
432
+ if (level != getCurrentLevel ()) {
433
+ setCurrentLevel (level );
434
+ }
435
+
436
+ float rotation = (nextIndex % INITIAL_CAPACITY ) * (360f / INITIAL_CAPACITY );
437
+ setHandRotation (rotation );
438
+ return true ;
439
+ }
440
+
441
+ return super .onKeyDown (keyCode , event );
442
+ }
443
+
378
444
private static float max3 (float a , float b , float c ) {
379
445
return max (max (a , b ), c );
380
446
}
@@ -387,4 +453,14 @@ int getCurrentLevel() {
387
453
void setCurrentLevel (@ Level int level ) {
388
454
clockHandView .setCurrentLevel (level );
389
455
}
456
+
457
+ public void setOnEnterKeyPressedListener (OnEnterKeyPressedListener onEnterKeyPressedListener ) {
458
+ this .onEnterKeyPressedListener = onEnterKeyPressedListener ;
459
+ }
460
+
461
+ /** Listener interface for enter key press events on the clock face. */
462
+ interface OnEnterKeyPressedListener {
463
+ /** Called when the enter key is pressed. */
464
+ void onEnterKeyPressed ();
465
+ }
390
466
}
0 commit comments