|
22 | 22 | import android.text.style.TextAppearanceSpan; |
23 | 23 | import android.util.AttributeSet; |
24 | 24 | import android.view.HapticFeedbackConstants; |
| 25 | +import android.view.MotionEvent; |
25 | 26 | import android.view.View; |
| 27 | +import android.view.accessibility.AccessibilityManager; |
26 | 28 | import android.widget.Button; |
27 | 29 | import android.widget.TextView; |
28 | 30 |
|
@@ -72,6 +74,7 @@ public NumPadKey(Context context, AttributeSet attrs, int defStyle) { |
72 | 74 | setTextViewResId(a.getResourceId(R.styleable.NumPadKey_textView, 0)); |
73 | 75 |
|
74 | 76 | setOnClickListener(mListener); |
| 77 | + setOnHoverListener(new LiftToActivateListener(context)); |
75 | 78 |
|
76 | 79 | mEnableHaptics = new LockPatternUtils(context).isTactileFeedbackEnabled(); |
77 | 80 |
|
@@ -113,4 +116,45 @@ public void doHapticKeyClick() { |
113 | 116 | | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); |
114 | 117 | } |
115 | 118 | } |
| 119 | + |
| 120 | + /** |
| 121 | + * Hover listener that implements lift-to-activate interaction for |
| 122 | + * accessibility. May be added to multiple views. |
| 123 | + */ |
| 124 | + static class LiftToActivateListener implements View.OnHoverListener { |
| 125 | + /** Manager used to query accessibility enabled state. */ |
| 126 | + private final AccessibilityManager mAccessibilityManager; |
| 127 | + |
| 128 | + public LiftToActivateListener(Context context) { |
| 129 | + mAccessibilityManager = (AccessibilityManager) context.getSystemService( |
| 130 | + Context.ACCESSIBILITY_SERVICE); |
| 131 | + } |
| 132 | + |
| 133 | + @Override |
| 134 | + public boolean onHover(View v, MotionEvent event) { |
| 135 | + // When touch exploration is turned on, lifting a finger while |
| 136 | + // inside the view bounds should perform a click action. |
| 137 | + if (mAccessibilityManager.isEnabled() |
| 138 | + && mAccessibilityManager.isTouchExplorationEnabled()) { |
| 139 | + switch (event.getActionMasked()) { |
| 140 | + case MotionEvent.ACTION_HOVER_ENTER: |
| 141 | + // Lift-to-type temporarily disables double-tap |
| 142 | + // activation. |
| 143 | + v.setClickable(false); |
| 144 | + break; |
| 145 | + case MotionEvent.ACTION_HOVER_EXIT: |
| 146 | + final int x = (int) event.getX(); |
| 147 | + final int y = (int) event.getY(); |
| 148 | + if ((x > v.getPaddingLeft()) && (y > v.getPaddingTop()) |
| 149 | + && (x < v.getWidth() - v.getPaddingRight()) |
| 150 | + && (y < v.getHeight() - v.getPaddingBottom())) { |
| 151 | + v.performClick(); |
| 152 | + } |
| 153 | + v.setClickable(true); |
| 154 | + break; |
| 155 | + } |
| 156 | + } |
| 157 | + return false; |
| 158 | + } |
| 159 | + } |
116 | 160 | } |
0 commit comments