react-native-external-keyboard 0.8.5 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -67
- package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegate.java +81 -75
- package/android/src/main/java/com/externalkeyboard/delegates/FocusOrderDelegateHost.java +14 -0
- package/android/src/main/java/com/externalkeyboard/helper/Linking/A11yOrderLinking.java +5 -0
- package/android/src/main/java/com/externalkeyboard/modules/ExternalKeyboardModule.java +10 -10
- package/android/src/main/java/com/externalkeyboard/services/FocusLinkObserver/FocusLinkObserver.java +26 -35
- package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/ExternalKeyboardLockView.java +5 -0
- package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/ExternalKeyboardLockViewManager.java +6 -0
- package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardView.java +8 -307
- package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardView/ExternalKeyboardViewManager.java +11 -18
- package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapper.java +208 -101
- package/android/src/main/java/com/externalkeyboard/views/TextInputFocusWrapper/TextInputFocusWrapperManager.java +123 -34
- package/android/src/main/java/com/externalkeyboard/views/base/FocusHighlightBase.java +38 -0
- package/android/src/main/java/com/externalkeyboard/views/base/ViewGroupBase.java +19 -0
- package/android/src/main/java/com/externalkeyboard/views/base/ViewOrderGroupBase.java +190 -0
- package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewFocusChangeBase.java +39 -0
- package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewFocusRequestBase.java +125 -0
- package/android/src/main/java/com/externalkeyboard/views/base/keyboard/ViewKeyHandlerBase.java +40 -0
- package/android/src/newarch/TextInputFocusWrapperManagerSpec.java +2 -8
- package/android/src/oldarch/ExternalKeyboardLockViewManagerSpec.java +1 -0
- package/android/src/oldarch/TextInputFocusWrapperManagerSpec.java +32 -2
- package/ios/Delegates/RNCEKVFocusLinkDelegate/RNCEKVFocusLinkDelegate.h +35 -0
- package/ios/Delegates/RNCEKVFocusLinkDelegate/RNCEKVFocusLinkDelegate.mm +195 -0
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderProtocol.h +6 -8
- package/ios/Delegates/RNCEKVFocusSequenceDelegate/RNCEKVFocusSequenceDelegate.h +25 -0
- package/ios/Delegates/RNCEKVFocusSequenceDelegate/RNCEKVFocusSequenceDelegate.mm +163 -0
- package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.h +2 -6
- package/ios/Delegates/RNCEKVGroupIdentifierDelegate/RNCEKVGroupIdentifierDelegate.mm +6 -78
- package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.h +3 -4
- package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloDelegate.mm +32 -101
- package/ios/Delegates/RNCEKVHaloDelegate/RNCEKVHaloProtocol.h +1 -1
- package/ios/Extensions/RCTEnhancedScrollView+RNCEKVExternalKeyboard.mm +1 -1
- package/ios/Extensions/RCTTextInputComponentView+RNCEKVExternalKeyboard.mm +15 -0
- package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.h +9 -6
- package/ios/Extensions/RCTViewComponentView+RNCEKVExternalKeyboard.mm +16 -29
- package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.h +1 -0
- package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.mm +8 -0
- package/ios/Helpers/RNCEKVNativeProps/RNCEKVNativeProps.h +123 -0
- package/ios/Protocols/RNCEKVCustomFocusEffectProtocol.h +15 -0
- package/ios/Protocols/RNCEKVCustomGroudIdProtocol.h +15 -0
- package/ios/Protocols/RNCEKVKeyboardFocusableProtocol.h +15 -0
- package/ios/Services/RNCEKVFocusLinkObserver.mm +2 -3
- package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVOrderRelationship/RNCEKVOrderRelationship.mm +15 -28
- package/ios/Services/RNCEKVOrderLinking.mm +43 -51
- package/ios/Views/Base/ContextMenu/RNCEKVViewContextMenuBase.h +33 -0
- package/ios/Views/Base/ContextMenu/RNCEKVViewContextMenuBase.mm +84 -0
- package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.h +37 -0
- package/ios/Views/Base/FocusChange/RNCEKVViewFocusChangeBase.mm +89 -0
- package/ios/Views/Base/FocusOrderGroup/RNCEKVViewOrderGroupBase.h +49 -0
- package/ios/Views/Base/FocusOrderGroup/RNCEKVViewOrderGroupBase.mm +245 -0
- package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.h +34 -0
- package/ios/Views/Base/FocusRequest/RNCEKVViewFocusRequestBase.mm +112 -0
- package/ios/Views/Base/GroupIdentifier/RNCEKVViewGroupIdentifierBase.h +27 -0
- package/ios/Views/Base/GroupIdentifier/RNCEKVViewGroupIdentifierBase.mm +69 -0
- package/ios/Views/Base/KeyPress/RNCEKVViewKeyPress.h +30 -0
- package/ios/Views/Base/KeyPress/RNCEKVViewKeyPress.mm +75 -0
- package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.h +33 -0
- package/ios/Views/Base/KeyboardHallo/RNCEKVExternalKeyboardHalloBase.mm +92 -0
- package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.h +36 -0
- package/ios/Views/Base/ViewGroup/RNCEKVViewGroupBase.mm +63 -0
- package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockView.h +8 -0
- package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockView.mm +105 -2
- package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockViewManager.mm +11 -0
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.h +7 -82
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +23 -493
- package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardViewManager.mm +5 -7
- package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.mm +20 -17
- package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.h +10 -39
- package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.mm +40 -73
- package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapperManager.mm +76 -8
- package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js +35 -7
- package/lib/commonjs/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
- package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js +79 -1
- package/lib/commonjs/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
- package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.js +18 -4
- package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.js.map +1 -1
- package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +17 -2
- package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -1
- package/lib/commonjs/components/KeyboardFocusView/KeyboardFocusView.js +2 -0
- package/lib/commonjs/components/KeyboardFocusView/KeyboardFocusView.js.map +1 -1
- package/lib/commonjs/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -0
- package/lib/commonjs/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
- package/lib/commonjs/utils/useFocusStyle.js +3 -9
- package/lib/commonjs/utils/useFocusStyle.js.map +1 -1
- package/lib/commonjs/utils/withKeyboardFocus.js +32 -15
- package/lib/commonjs/utils/withKeyboardFocus.js.map +1 -1
- package/lib/commonjs/utils/wrapOrderPrefix.js +17 -0
- package/lib/commonjs/utils/wrapOrderPrefix.js.map +1 -0
- package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js +35 -7
- package/lib/module/components/BaseKeyboardView/BaseKeyboardView.js.map +1 -1
- package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js +80 -2
- package/lib/module/components/KeyboardExtendedInput/KeyboardExtendedInput.js.map +1 -1
- package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.js +18 -4
- package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.js.map +1 -1
- package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +16 -2
- package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -1
- package/lib/module/components/KeyboardFocusView/KeyboardFocusView.js +2 -0
- package/lib/module/components/KeyboardFocusView/KeyboardFocusView.js.map +1 -1
- package/lib/module/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -0
- package/lib/module/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
- package/lib/module/utils/useFocusStyle.js +4 -10
- package/lib/module/utils/useFocusStyle.js.map +1 -1
- package/lib/module/utils/withKeyboardFocus.js +32 -15
- package/lib/module/utils/withKeyboardFocus.js.map +1 -1
- package/lib/module/utils/wrapOrderPrefix.js +12 -0
- package/lib/module/utils/wrapOrderPrefix.js.map +1 -0
- package/lib/typescript/src/components/BaseKeyboardView/BaseKeyboardView.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts +15 -0
- package/lib/typescript/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts +1 -1
- package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts +2 -1
- package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts.map +1 -1
- package/lib/typescript/src/components/KeyboardFocusView/KeyboardFocusView.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts +1 -0
- package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts +16 -1
- package/lib/typescript/src/nativeSpec/TextInputFocusWrapperNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/types/BaseKeyboardView.d.ts +2 -0
- package/lib/typescript/src/types/BaseKeyboardView.d.ts.map +1 -1
- package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts +1 -0
- package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts.map +1 -1
- package/lib/typescript/src/types/WithKeyboardFocus.d.ts +11 -2
- package/lib/typescript/src/types/WithKeyboardFocus.d.ts.map +1 -1
- package/lib/typescript/src/utils/useFocusStyle.d.ts +1 -0
- package/lib/typescript/src/utils/useFocusStyle.d.ts.map +1 -1
- package/lib/typescript/src/utils/withKeyboardFocus.d.ts.map +1 -1
- package/lib/typescript/src/utils/wrapOrderPrefix.d.ts +9 -0
- package/lib/typescript/src/utils/wrapOrderPrefix.d.ts.map +1 -0
- package/package.json +6 -2
- package/src/components/BaseKeyboardView/BaseKeyboardView.tsx +88 -10
- package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.tsx +138 -2
- package/src/components/KeyboardExtendedInput/KeyboardExtendedInput.types.ts +15 -0
- package/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.tsx +21 -4
- package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.tsx +20 -3
- package/src/components/KeyboardFocusView/KeyboardFocusView.tsx +2 -0
- package/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +1 -0
- package/src/nativeSpec/TextInputFocusWrapperNativeComponent.ts +16 -0
- package/src/types/BaseKeyboardView.ts +2 -0
- package/src/types/KeyboardFocusLock.types.ts +1 -0
- package/src/types/WithKeyboardFocus.ts +19 -2
- package/src/utils/useFocusStyle.tsx +5 -15
- package/src/utils/withKeyboardFocus.tsx +44 -15
- package/src/utils/wrapOrderPrefix.ts +16 -0
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.h +0 -36
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.mm +0 -150
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.h +0 -47
- package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.mm +0 -326
- package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVKeyboardOrderManager.h +0 -17
- package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVKeyboardOrderManager.mm +0 -15
- package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js +0 -22
- package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js.map +0 -1
- package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js +0 -17
- package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js.map +0 -1
- package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.d.ts +0 -4
- package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.d.ts.map +0 -1
- package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.tsx +0 -16
|
@@ -2,40 +2,42 @@ package com.externalkeyboard.views.TextInputFocusWrapper;
|
|
|
2
2
|
|
|
3
3
|
import android.content.Context;
|
|
4
4
|
import android.graphics.Rect;
|
|
5
|
+
import android.os.Build;
|
|
5
6
|
import android.text.Editable;
|
|
6
7
|
import android.view.KeyEvent;
|
|
8
|
+
import android.view.MotionEvent;
|
|
7
9
|
import android.view.View;
|
|
8
|
-
import android.view.ViewGroup;
|
|
9
10
|
import android.widget.EditText;
|
|
10
11
|
|
|
11
12
|
import androidx.annotation.NonNull;
|
|
12
13
|
|
|
13
14
|
import com.externalkeyboard.events.EventHelper;
|
|
14
|
-
import com.externalkeyboard.helper.ReactNativeVersionChecker;
|
|
15
15
|
import com.externalkeyboard.modules.ExternalKeyboardModule;
|
|
16
|
+
import com.externalkeyboard.views.base.FocusHighlightBase;
|
|
16
17
|
import com.facebook.react.bridge.ReactContext;
|
|
17
|
-
import com.facebook.react.modules.systeminfo.ReactNativeVersion;
|
|
18
18
|
import com.facebook.react.views.textinput.ReactEditText;
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
public class TextInputFocusWrapper extends ViewGroup implements View.OnFocusChangeListener {
|
|
20
|
+
public class TextInputFocusWrapper extends FocusHighlightBase implements View.OnFocusChangeListener {
|
|
23
21
|
private final Context context;
|
|
24
22
|
public static final byte FOCUS_BY_PRESS = 1;
|
|
23
|
+
|
|
24
|
+
// RN version is a compile-time constant — cache it once instead of re-reading on every call.
|
|
25
|
+
private static final boolean IS_NATIVELY_FIXED_VERSION = resolveIsNativelyFixedVersion();
|
|
26
|
+
|
|
25
27
|
private ReactEditText reactEditText = null;
|
|
26
28
|
private boolean focusEventIgnore = false;
|
|
27
29
|
private int focusType = 0;
|
|
28
|
-
|
|
30
|
+
// Used only to re-apply focusability after React Native attaches the EditText to the window.
|
|
31
|
+
private View.OnAttachStateChangeListener focusabilityListener;
|
|
29
32
|
private boolean blurOnSubmit = true;
|
|
30
33
|
private boolean multiline = false;
|
|
31
34
|
private boolean keyboardFocusable = true;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return focusType == FOCUS_BY_PRESS;
|
|
35
|
-
}
|
|
36
|
-
private boolean getIsNativelyFixedVersion () {
|
|
35
|
+
|
|
36
|
+
private static boolean resolveIsNativelyFixedVersion() {
|
|
37
37
|
try {
|
|
38
|
-
Object minorValue = ReactNativeVersion.VERSION.
|
|
38
|
+
Object minorValue = com.facebook.react.modules.systeminfo.ReactNativeVersion.VERSION.containsKey("minor")
|
|
39
|
+
? com.facebook.react.modules.systeminfo.ReactNativeVersion.VERSION.get("minor")
|
|
40
|
+
: 0;
|
|
39
41
|
int minor = (minorValue instanceof Integer) ? (int) minorValue : 0;
|
|
40
42
|
return minor >= 79;
|
|
41
43
|
} catch (Exception e) {
|
|
@@ -43,84 +45,141 @@ public class TextInputFocusWrapper extends ViewGroup implements View.OnFocusChan
|
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
// For FOCUS_BY_PRESS: wrapper must always intercept focus so the user navigates
|
|
49
|
+
// to the wrapper first, then presses Enter/Space to enter edit mode.
|
|
50
|
+
// For regular focus: pre-0.79 had a backward-direction bug, so the wrapper handled
|
|
51
|
+
// focus transfer. In 0.79+ that is natively fixed and the EditText gets focus directly.
|
|
52
|
+
private boolean shouldWrapperBeFocusable() {
|
|
53
|
+
if (!keyboardFocusable) return false;
|
|
54
|
+
if (focusType == FOCUS_BY_PRESS) return true;
|
|
55
|
+
return !IS_NATIVELY_FIXED_VERSION;
|
|
56
|
+
}
|
|
50
57
|
|
|
51
|
-
|
|
58
|
+
private boolean shouldEditTextBeFocusable() {
|
|
59
|
+
return keyboardFocusable && !shouldWrapperBeFocusable();
|
|
60
|
+
}
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
private void updateFocusability() {
|
|
63
|
+
this.setFocusable(shouldWrapperBeFocusable());
|
|
54
64
|
if (this.reactEditText != null) {
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
this.reactEditText.setFocusable(shouldEditTextBeFocusable());
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@Override
|
|
70
|
+
protected void syncFocusHighlight () {
|
|
71
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
72
|
+
|
|
73
|
+
this.setDefaultFocusHighlightEnabled(focusHighlight);
|
|
74
|
+
if(this.reactEditText != null) {
|
|
75
|
+
reactEditText.setDefaultFocusHighlightEnabled(focusHighlight);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@Override
|
|
82
|
+
public View getFirstChild() {
|
|
83
|
+
// In 0.79+ with regular focus, the EditText receives focus directly.
|
|
84
|
+
// For FOCUS_BY_PRESS the wrapper itself is the focus target.
|
|
85
|
+
if (IS_NATIVELY_FIXED_VERSION && focusType != FOCUS_BY_PRESS && this.reactEditText != null) {
|
|
86
|
+
return this.reactEditText;
|
|
87
|
+
}
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Override
|
|
92
|
+
public void setNextFocusForwardId(int nextFocusForwardId) {
|
|
93
|
+
super.setNextFocusForwardId(nextFocusForwardId);
|
|
94
|
+
if (reactEditText != null) {
|
|
95
|
+
reactEditText.setNextFocusForwardId(nextFocusForwardId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// --- Child lifecycle (mirrors ExternalKeyboardView pattern) ---
|
|
100
|
+
|
|
101
|
+
// Overrides ViewOrderGroupBase.linkAddView so the manager can call it uniformly
|
|
102
|
+
// for all children — the ReactEditText filter lives here, not in the manager.
|
|
103
|
+
@Override
|
|
104
|
+
public void linkAddView(View child) {
|
|
105
|
+
if (!(child instanceof ReactEditText)) return;
|
|
106
|
+
setEditText((ReactEditText) child); // configure listeners before linking
|
|
107
|
+
this.syncFocusHighlight();
|
|
108
|
+
super.linkAddView(child); // store firstChild + call focusOrderDelegate.link()
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Symmetric to linkAddView: manager calls linkRemoveView for all children.
|
|
112
|
+
@Override
|
|
113
|
+
public void linkRemoveView(View view) {
|
|
114
|
+
if (view != this.reactEditText) return;
|
|
115
|
+
super.linkRemoveView(view); // call focusOrderDelegate.unlink() + clear firstChild
|
|
116
|
+
setEditText(null);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// --- EditText setup / teardown ---
|
|
120
|
+
|
|
121
|
+
public void setEditText(ReactEditText editText) {
|
|
122
|
+
if (editText != null) {
|
|
123
|
+
this.reactEditText = editText;
|
|
124
|
+
updateFocusability();
|
|
125
|
+
this.reactEditText.addOnAttachStateChangeListener(getFocusabilityListener());
|
|
126
|
+
subscribeEditTextFocusListener();
|
|
127
|
+
onMultiplyBlurSubmitHandle();
|
|
128
|
+
} else {
|
|
129
|
+
clearEditText();
|
|
57
130
|
}
|
|
58
131
|
}
|
|
59
132
|
|
|
60
|
-
private View.OnAttachStateChangeListener
|
|
61
|
-
if (
|
|
62
|
-
|
|
133
|
+
private View.OnAttachStateChangeListener getFocusabilityListener() {
|
|
134
|
+
if (focusabilityListener == null) {
|
|
135
|
+
focusabilityListener = new View.OnAttachStateChangeListener() {
|
|
63
136
|
@Override
|
|
64
137
|
public void onViewAttachedToWindow(@NonNull View view) {
|
|
65
|
-
|
|
66
|
-
|
|
138
|
+
// Re-apply focusability after React Native attaches the view; the
|
|
139
|
+
// framework may reset it during the layout/commit phase.
|
|
140
|
+
view.setFocusable(shouldEditTextBeFocusable());
|
|
67
141
|
}
|
|
68
|
-
|
|
69
142
|
@Override
|
|
70
|
-
public void onViewDetachedFromWindow(@NonNull View view) {
|
|
71
|
-
}
|
|
143
|
+
public void onViewDetachedFromWindow(@NonNull View view) {}
|
|
72
144
|
};
|
|
73
145
|
}
|
|
74
|
-
return
|
|
146
|
+
return focusabilityListener;
|
|
75
147
|
}
|
|
76
148
|
|
|
77
149
|
private void clearEditText() {
|
|
78
150
|
if (this.reactEditText != null) {
|
|
151
|
+
focusOrderDelegate.unlink();
|
|
152
|
+
if (focusabilityListener != null) {
|
|
153
|
+
this.reactEditText.removeOnAttachStateChangeListener(focusabilityListener);
|
|
154
|
+
}
|
|
79
155
|
this.reactEditText.setOnFocusChangeListener(null);
|
|
80
156
|
this.reactEditText.setOnKeyListener(null);
|
|
81
|
-
|
|
82
|
-
if (onAttachListener != null) {
|
|
83
|
-
this.reactEditText.removeOnAttachStateChangeListener(onAttachListener);
|
|
84
|
-
}
|
|
85
157
|
}
|
|
86
158
|
this.reactEditText = null;
|
|
87
159
|
}
|
|
88
160
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
161
|
+
private void subscribeEditTextFocusListener() {
|
|
162
|
+
OnFocusChangeListener reactListener = this.reactEditText.getOnFocusChangeListener();
|
|
163
|
+
this.reactEditText.setOnFocusChangeListener((textInput, hasTextEditFocus) -> {
|
|
164
|
+
reactListener.onFocusChange(textInput, hasTextEditFocus);
|
|
165
|
+
this.focusEventIgnore = false;
|
|
166
|
+
if (focusType != FOCUS_BY_PRESS || !hasTextEditFocus) {
|
|
167
|
+
onFocusChange(textInput, hasTextEditFocus);
|
|
95
168
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (focusType == FOCUS_BY_PRESS) {
|
|
99
|
-
this.reactEditText.setFocusable(isAlreadyFixed);
|
|
169
|
+
if (hasTextEditFocus) {
|
|
170
|
+
ExternalKeyboardModule.setFocusedTextInput(textInput);
|
|
100
171
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.focusEventIgnore = false;
|
|
106
|
-
if (focusType != FOCUS_BY_PRESS || !hasTextEditFocus) {
|
|
107
|
-
onFocusChange(textInput, hasTextEditFocus);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (hasTextEditFocus) {
|
|
111
|
-
ExternalKeyboardModule.setFocusedTextInput(textInput);
|
|
112
|
-
}
|
|
113
|
-
if (!hasTextEditFocus) {
|
|
114
|
-
this.setFocusable(!isAlreadyFixed);
|
|
115
|
-
this.reactEditText.setFocusable(isAlreadyFixed);
|
|
172
|
+
if (!hasTextEditFocus) {
|
|
173
|
+
updateFocusability();
|
|
174
|
+
if (focusType == FOCUS_BY_PRESS) {
|
|
175
|
+
post(() -> TextInputFocusWrapper.this.requestFocus());
|
|
116
176
|
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
} else {
|
|
120
|
-
this.clearEditText();
|
|
121
|
-
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
122
179
|
}
|
|
123
180
|
|
|
181
|
+
// --- Focus change event ---
|
|
182
|
+
|
|
124
183
|
@Override
|
|
125
184
|
public void onFocusChange(View v, boolean hasFocus) {
|
|
126
185
|
if (!this.focusEventIgnore) {
|
|
@@ -132,22 +191,29 @@ public class TextInputFocusWrapper extends ViewGroup implements View.OnFocusChan
|
|
|
132
191
|
this.setOnFocusChangeListener(this);
|
|
133
192
|
}
|
|
134
193
|
|
|
194
|
+
// --- Props ---
|
|
195
|
+
|
|
196
|
+
public void setKeyboardFocusable(boolean canBeFocusable) {
|
|
197
|
+
if (keyboardFocusable == canBeFocusable) return;
|
|
198
|
+
keyboardFocusable = canBeFocusable;
|
|
199
|
+
updateFocusability();
|
|
200
|
+
}
|
|
201
|
+
|
|
135
202
|
public void setFocusType(int focusType) {
|
|
203
|
+
if (this.focusType == focusType) return;
|
|
136
204
|
this.focusType = focusType;
|
|
205
|
+
updateFocusability();
|
|
206
|
+
// On 0.79+ getFirstChild() switches between wrapper and reactEditText based on
|
|
207
|
+
// focusType. If the EditText is already attached, re-link so the delegate
|
|
208
|
+
// registers the correct child for the new mode.
|
|
209
|
+
if (reactEditText != null && reactEditText.isAttachedToWindow()) {
|
|
210
|
+
focusOrderDelegate.unlink();
|
|
211
|
+
focusOrderDelegate.link();
|
|
212
|
+
}
|
|
137
213
|
}
|
|
138
214
|
|
|
139
215
|
public void setBlurType(int blurType) {
|
|
140
|
-
// Stub
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
public TextInputFocusWrapper(Context context) {
|
|
144
|
-
super(context);
|
|
145
|
-
this.context = context;
|
|
146
|
-
|
|
147
|
-
if (keyboardFocusable) {
|
|
148
|
-
boolean isAlreadyFixed = getIsNativelyFixedVersion();
|
|
149
|
-
setFocusable(!isAlreadyFixed);
|
|
150
|
-
}
|
|
216
|
+
// Stub: Android does not allow typing in an EditText from another view.
|
|
151
217
|
}
|
|
152
218
|
|
|
153
219
|
public void setBlurOnSubmit(boolean blurOnSubmit) {
|
|
@@ -159,9 +225,20 @@ public class TextInputFocusWrapper extends ViewGroup implements View.OnFocusChan
|
|
|
159
225
|
onMultiplyBlurSubmitHandle();
|
|
160
226
|
}
|
|
161
227
|
|
|
228
|
+
// --- Constructor ---
|
|
229
|
+
|
|
230
|
+
public TextInputFocusWrapper(Context context) {
|
|
231
|
+
super(context);
|
|
232
|
+
this.context = context;
|
|
233
|
+
setFocusable(shouldWrapperBeFocusable());
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// --- Key handling ---
|
|
237
|
+
|
|
162
238
|
@Override
|
|
163
239
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
164
|
-
if (
|
|
240
|
+
if (isFocusLocked(event)) return true;
|
|
241
|
+
if (focusType == FOCUS_BY_PRESS && this.reactEditText != null) {
|
|
165
242
|
this.reactEditText.setFocusable(false);
|
|
166
243
|
}
|
|
167
244
|
if (keyCode == KeyEvent.KEYCODE_SPACE || keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
|
|
@@ -171,36 +248,69 @@ public class TextInputFocusWrapper extends ViewGroup implements View.OnFocusChan
|
|
|
171
248
|
return super.onKeyDown(keyCode, event);
|
|
172
249
|
}
|
|
173
250
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
251
|
+
// --- Touch handling ---
|
|
252
|
+
|
|
253
|
+
@Override
|
|
254
|
+
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
|
255
|
+
// In FOCUS_BY_PRESS mode the EditText is non-focusable (wrapper holds focus).
|
|
256
|
+
// Intercept the down event so a tap activates edit mode, same as a keyboard press.
|
|
257
|
+
if (focusType == FOCUS_BY_PRESS && ev.getAction() == MotionEvent.ACTION_DOWN) {
|
|
258
|
+
handleTextInputFocus();
|
|
178
259
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
260
|
+
return false; // don't consume — let the touch reach the EditText for cursor positioning
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// --- Focus search / request ---
|
|
264
|
+
|
|
265
|
+
@Override
|
|
266
|
+
public View focusSearch(int direction) {
|
|
267
|
+
// focusSearch(View, int) is only called when a descendant is focused.
|
|
268
|
+
// When the wrapper itself is focused (FOCUS_BY_PRESS idle state), we must
|
|
269
|
+
// handle orderForward/orderBackward here instead.
|
|
270
|
+
|
|
271
|
+
if (focusType == FOCUS_BY_PRESS) {
|
|
272
|
+
if (direction == FOCUS_FORWARD && orderForward != null) {
|
|
273
|
+
View next = focusOrderDelegate.getLink(orderForward);
|
|
274
|
+
if (next != null && next.isAttachedToWindow()) return next;
|
|
275
|
+
}
|
|
276
|
+
if (direction == FOCUS_BACKWARD && orderBackward != null) {
|
|
277
|
+
View prev = focusOrderDelegate.getLink(orderBackward);
|
|
278
|
+
if (prev != null && prev.isAttachedToWindow()) return prev;
|
|
279
|
+
}
|
|
182
280
|
}
|
|
281
|
+
return super.focusSearch(direction);
|
|
282
|
+
}
|
|
183
283
|
|
|
284
|
+
@Override
|
|
285
|
+
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
|
|
286
|
+
if (focusType != FOCUS_BY_PRESS) {
|
|
287
|
+
// 0.79+: wrapper is not focusable, pass through.
|
|
288
|
+
if (IS_NATIVELY_FIXED_VERSION) return super.requestFocus(direction, previouslyFocusedRect);
|
|
289
|
+
// Pre-0.79: intercept forward/backward and transfer focus directly to EditText.
|
|
290
|
+
if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
|
|
291
|
+
this.handleTextInputFocus();
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
184
295
|
return super.requestFocus(direction, previouslyFocusedRect);
|
|
185
296
|
}
|
|
186
297
|
|
|
298
|
+
// --- Internal helpers ---
|
|
299
|
+
|
|
187
300
|
private void onMultiplyBlurSubmitHandle() {
|
|
188
301
|
if (this.reactEditText == null) return;
|
|
189
302
|
if (this.multiline) {
|
|
190
|
-
this.reactEditText.setOnKeyListener(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
v.clearFocus();
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
303
|
+
this.reactEditText.setOnKeyListener((v, keyCode, event) -> {
|
|
304
|
+
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER && !event.isShiftPressed()) {
|
|
305
|
+
Editable editableText = reactEditText.getText();
|
|
306
|
+
String text = editableText == null ? "" : String.valueOf(editableText);
|
|
307
|
+
EventHelper.multiplyTextSubmit((ReactContext) context, getId(), text);
|
|
308
|
+
if (blurOnSubmit && v instanceof EditText) {
|
|
309
|
+
v.clearFocus();
|
|
310
|
+
return true;
|
|
201
311
|
}
|
|
202
|
-
return false;
|
|
203
312
|
}
|
|
313
|
+
return false;
|
|
204
314
|
});
|
|
205
315
|
} else {
|
|
206
316
|
this.reactEditText.setOnKeyListener(null);
|
|
@@ -211,14 +321,11 @@ public class TextInputFocusWrapper extends ViewGroup implements View.OnFocusChan
|
|
|
211
321
|
this.focusEventIgnore = true;
|
|
212
322
|
this.setFocusable(false);
|
|
213
323
|
this.reactEditText.setFocusable(true);
|
|
214
|
-
|
|
324
|
+
// focusableInTouchMode is required for requestFocus() to succeed when the device
|
|
325
|
+
// is in touch mode (canTakeFocus() returns false without it).
|
|
326
|
+
this.reactEditText.setFocusableInTouchMode(true);
|
|
215
327
|
if (!this.reactEditText.hasFocus()) {
|
|
216
328
|
this.reactEditText.requestFocusFromJS();
|
|
217
329
|
}
|
|
218
330
|
}
|
|
219
|
-
|
|
220
|
-
@Override
|
|
221
|
-
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
222
|
-
// No-op since UIManagerModule handles actually laying out children.
|
|
223
|
-
}
|
|
224
331
|
}
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
package com.externalkeyboard.views.TextInputFocusWrapper;
|
|
2
2
|
|
|
3
|
-
import android.view.View;
|
|
4
|
-
import android.view.ViewGroup;
|
|
5
|
-
|
|
6
3
|
import androidx.annotation.NonNull;
|
|
7
4
|
import androidx.annotation.Nullable;
|
|
8
5
|
|
|
6
|
+
import java.util.Objects;
|
|
7
|
+
|
|
9
8
|
import com.externalkeyboard.events.FocusChangeEvent;
|
|
10
9
|
import com.externalkeyboard.events.MultiplyTextSubmit;
|
|
11
|
-
import com.externalkeyboard.views.ExternalKeyboardView.ExternalKeyboardView;
|
|
12
|
-
import com.facebook.react.bridge.ReadableArray;
|
|
13
|
-
import com.facebook.react.common.MapBuilder;
|
|
14
10
|
import com.facebook.react.module.annotations.ReactModule;
|
|
15
11
|
import com.facebook.react.uimanager.ThemedReactContext;
|
|
16
12
|
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
17
|
-
import com.facebook.react.views.textinput.ReactEditText;
|
|
18
13
|
import com.facebook.react.views.view.ReactViewGroup;
|
|
19
14
|
|
|
20
15
|
import java.util.HashMap;
|
|
@@ -32,32 +27,14 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
|
|
|
32
27
|
|
|
33
28
|
@Override
|
|
34
29
|
public TextInputFocusWrapper createViewInstance(ThemedReactContext context) {
|
|
35
|
-
return
|
|
30
|
+
return new TextInputFocusWrapper(context);
|
|
36
31
|
}
|
|
37
32
|
|
|
38
33
|
@Override
|
|
39
|
-
protected void addEventEmitters(final ThemedReactContext reactContext,
|
|
40
|
-
viewGroup
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
protected TextInputFocusWrapper subscribeOnHierarchy(TextInputFocusWrapper viewGroup) {
|
|
44
|
-
viewGroup.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
|
|
45
|
-
@Override
|
|
46
|
-
public void onChildViewAdded(View parent, View child) {
|
|
47
|
-
if (child instanceof ReactEditText) {
|
|
48
|
-
viewGroup.setEditText((ReactEditText) child);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@Override
|
|
53
|
-
public void onChildViewRemoved(View parent, View child) {
|
|
54
|
-
if (child instanceof ReactEditText) {
|
|
55
|
-
viewGroup.setEditText(null);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return viewGroup;
|
|
34
|
+
protected void addEventEmitters(final ThemedReactContext reactContext, ReactViewGroup viewGroup) {
|
|
35
|
+
if(viewGroup instanceof TextInputFocusWrapper) {
|
|
36
|
+
((TextInputFocusWrapper)viewGroup).subscribeOnFocus();
|
|
37
|
+
}
|
|
61
38
|
}
|
|
62
39
|
|
|
63
40
|
@Override
|
|
@@ -89,6 +66,96 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
|
|
|
89
66
|
//stub
|
|
90
67
|
}
|
|
91
68
|
|
|
69
|
+
@Override
|
|
70
|
+
@ReactProp(name = "orderGroup")
|
|
71
|
+
public void setOrderGroup(TextInputFocusWrapper view, @Nullable String value) {
|
|
72
|
+
if (!Objects.equals(view.getOrderGroup(), value)) {
|
|
73
|
+
view.setOrderGroup(value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Override
|
|
78
|
+
@ReactProp(name = "orderIndex")
|
|
79
|
+
public void setOrderIndex(TextInputFocusWrapper view, int value) {
|
|
80
|
+
if (!Objects.equals(view.getOrderIndex(), value)) {
|
|
81
|
+
view.setOrderIndex(value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Override
|
|
86
|
+
@ReactProp(name = "orderId")
|
|
87
|
+
public void setOrderId(TextInputFocusWrapper view, @Nullable String value) {
|
|
88
|
+
if (!Objects.equals(view.orderId, value)) {
|
|
89
|
+
view.orderId = value;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Override
|
|
94
|
+
@ReactProp(name = "orderLeft")
|
|
95
|
+
public void setOrderLeft(TextInputFocusWrapper view, @Nullable String value) {
|
|
96
|
+
if (!Objects.equals(view.getOrderLeft(), value)) {
|
|
97
|
+
view.setOrderLeft(value);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@Override
|
|
102
|
+
@ReactProp(name = "orderRight")
|
|
103
|
+
public void setOrderRight(TextInputFocusWrapper view, @Nullable String value) {
|
|
104
|
+
if (!Objects.equals(view.getOrderRight(), value)) {
|
|
105
|
+
view.setOrderRight(value);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
@Override
|
|
110
|
+
@ReactProp(name = "orderUp")
|
|
111
|
+
public void setOrderUp(TextInputFocusWrapper view, @Nullable String value) {
|
|
112
|
+
if (!Objects.equals(view.getOrderUp(), value)) {
|
|
113
|
+
view.setOrderUp(value);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@Override
|
|
118
|
+
@ReactProp(name = "orderDown")
|
|
119
|
+
public void setOrderDown(TextInputFocusWrapper view, @Nullable String value) {
|
|
120
|
+
if (!Objects.equals(view.getOrderDown(), value)) {
|
|
121
|
+
view.setOrderDown(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@Override
|
|
126
|
+
@ReactProp(name = "orderForward")
|
|
127
|
+
public void setOrderForward(TextInputFocusWrapper view, @Nullable String value) {
|
|
128
|
+
if (!Objects.equals(view.orderForward, value)) {
|
|
129
|
+
view.orderForward = value;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@Override
|
|
134
|
+
@ReactProp(name = "orderBackward")
|
|
135
|
+
public void setOrderBackward(TextInputFocusWrapper view, @Nullable String value) {
|
|
136
|
+
if (!Objects.equals(view.orderBackward, value)) {
|
|
137
|
+
view.orderBackward = value;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@Override
|
|
142
|
+
@ReactProp(name = "lockFocus")
|
|
143
|
+
public void setLockFocus(TextInputFocusWrapper view, int value) {
|
|
144
|
+
if (view.lockFocus != value) {
|
|
145
|
+
view.lockFocus = value;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@Override
|
|
150
|
+
public void setOrderFirst(TextInputFocusWrapper view, @Nullable String value) {
|
|
151
|
+
//stub
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@Override
|
|
155
|
+
public void setOrderLast(TextInputFocusWrapper view, @Nullable String value) {
|
|
156
|
+
//stub
|
|
157
|
+
}
|
|
158
|
+
|
|
92
159
|
|
|
93
160
|
@Override
|
|
94
161
|
@ReactProp(name = "canBeFocused", defaultBoolean = true)
|
|
@@ -97,8 +164,9 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
|
|
|
97
164
|
}
|
|
98
165
|
|
|
99
166
|
@Override
|
|
167
|
+
@ReactProp(name = "haloEffect", defaultBoolean = true)
|
|
100
168
|
public void setHaloEffect(TextInputFocusWrapper view, boolean value) {
|
|
101
|
-
|
|
169
|
+
view.setFocusHighlight(value);
|
|
102
170
|
}
|
|
103
171
|
|
|
104
172
|
@Override
|
|
@@ -107,9 +175,12 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
|
|
|
107
175
|
}
|
|
108
176
|
|
|
109
177
|
@Override
|
|
110
|
-
public void onDropViewInstance(@NonNull
|
|
111
|
-
viewGroup
|
|
112
|
-
|
|
178
|
+
public void onDropViewInstance(@NonNull ReactViewGroup viewGroup) {
|
|
179
|
+
if(viewGroup instanceof TextInputFocusWrapper) {
|
|
180
|
+
((TextInputFocusWrapper)viewGroup).onDropViewInstance();
|
|
181
|
+
((TextInputFocusWrapper)viewGroup).setEditText(null);
|
|
182
|
+
viewGroup.setOnFocusChangeListener(null);
|
|
183
|
+
}
|
|
113
184
|
super.onDropViewInstance(viewGroup);
|
|
114
185
|
}
|
|
115
186
|
|
|
@@ -129,4 +200,22 @@ public class TextInputFocusWrapperManager extends com.externalkeyboard.TextInput
|
|
|
129
200
|
|
|
130
201
|
return export;
|
|
131
202
|
}
|
|
203
|
+
|
|
204
|
+
@Override
|
|
205
|
+
@ReactProp(name = "haloExpendY")
|
|
206
|
+
public void setHaloExpendY(TextInputFocusWrapper view, float value) {
|
|
207
|
+
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@Override
|
|
211
|
+
@ReactProp(name = "haloExpendX")
|
|
212
|
+
public void setHaloExpendX(TextInputFocusWrapper view, float value) {
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
@Override
|
|
217
|
+
@ReactProp(name = "haloCornerRadius")
|
|
218
|
+
public void setHaloCornerRadius(TextInputFocusWrapper view, float value) {
|
|
219
|
+
|
|
220
|
+
}
|
|
132
221
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package com.externalkeyboard.views.base;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.os.Build;
|
|
5
|
+
import android.view.View;
|
|
6
|
+
|
|
7
|
+
public class FocusHighlightBase extends ViewOrderGroupBase {
|
|
8
|
+
protected boolean focusHighlight = true;
|
|
9
|
+
|
|
10
|
+
public void setFocusHighlight (boolean defaultFocusHighlightEnabled) {
|
|
11
|
+
focusHighlight = defaultFocusHighlightEnabled;
|
|
12
|
+
syncFocusHighlight();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected View getFocusHighlightView () {
|
|
16
|
+
return this.getFirstChild();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected void syncFocusHighlight () {
|
|
20
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
21
|
+
View child = this.getFocusHighlightView();
|
|
22
|
+
if(child != null) {
|
|
23
|
+
child.setDefaultFocusHighlightEnabled(focusHighlight);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Override
|
|
29
|
+
public void linkAddView(View child) {
|
|
30
|
+
super.linkAddView(child);
|
|
31
|
+
syncFocusHighlight();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public FocusHighlightBase(Context context) {
|
|
35
|
+
super(context);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.externalkeyboard.views.base;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.view.View;
|
|
5
|
+
|
|
6
|
+
import com.externalkeyboard.helper.FocusHelper;
|
|
7
|
+
import com.facebook.react.views.view.ReactViewGroup;
|
|
8
|
+
|
|
9
|
+
public class ViewGroupBase extends ReactViewGroup {
|
|
10
|
+
|
|
11
|
+
public ViewGroupBase(Context context) {
|
|
12
|
+
super(context);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected View getFocusingView() {
|
|
16
|
+
View focusableView = FocusHelper.getFocusableView(this);
|
|
17
|
+
return focusableView != null ? focusableView : this;
|
|
18
|
+
}
|
|
19
|
+
}
|