-
Notifications
You must be signed in to change notification settings - Fork 24.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement onKeyPress Android #14720
Implement onKeyPress Android #14720
Changes from 1 commit
fd566f3
74ccc2e
71124c0
7ad03a2
3efb3de
d37a01a
17085da
0a1bcc4
a330280
a1bf94f
97cc740
7fd20d1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,8 @@ | |
|
||
import javax.annotation.Nullable; | ||
|
||
import android.view.KeyEvent; | ||
import android.view.inputmethod.CorrectionInfo; | ||
import android.view.inputmethod.EditorInfo; | ||
import android.view.inputmethod.InputConnection; | ||
import android.view.inputmethod.InputConnectionWrapper; | ||
|
@@ -65,17 +67,15 @@ | |
* input, and then set the composing text to be the character the user entered. In this case we | ||
* choose our onKeyPress to be the new composing character. | ||
*/ | ||
class ReactTextInputInputConnection extends InputConnectionWrapper { | ||
class ReactTextInputInputConnection extends InputConnectionWrapper { | ||
public static final String NewLineRawValue = "\n"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. public static final fields should be all caps with underscores: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! |
||
public static final String BackspaceKeyValue = "Backspace"; | ||
public static final String EnterKeyValue = "Enter"; | ||
|
||
private @Nullable ReactEditText mEditText; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, with your suggested changes, |
||
private EventDispatcher mEventDispatcher; | ||
private int mPreviousSelectionStart; | ||
private int mPreviousSelectionEnd; | ||
private String mCommittedText; | ||
private String mComposedText; | ||
private boolean mIsBatchEdit; | ||
private String mKey = null; | ||
|
||
public ReactTextInputInputConnection( | ||
InputConnection target, | ||
|
@@ -89,67 +89,81 @@ public void setEditText(final ReactEditText editText) { | |
mEditText = editText; | ||
} | ||
|
||
@Override | ||
public boolean beginBatchEdit() { | ||
mIsBatchEdit = true; | ||
return super.beginBatchEdit(); | ||
} | ||
|
||
@Override | ||
public boolean endBatchEdit() { | ||
mIsBatchEdit = false; | ||
if(mKey != null) { | ||
dispatchKeyEvent(mKey); | ||
mKey = null; | ||
} | ||
return super.endBatchEdit(); | ||
} | ||
|
||
@Override | ||
public boolean setComposingText(CharSequence text, int newCursorPosition) { | ||
mComposedText = text.toString(); | ||
return super.setComposingText(text, newCursorPosition); | ||
final int previousSelectionStart = mEditText.getSelectionStart(); | ||
final int previousSelectionEnd = mEditText.getSelectionEnd(); | ||
String key; | ||
final boolean consumed = super.setComposingText(text, newCursorPosition); | ||
final boolean noPreviousSelection = previousSelectionStart == previousSelectionEnd; | ||
if ((noPreviousSelection && mEditText.getSelectionStart() < previousSelectionStart) | ||
|| !noPreviousSelection && mEditText.getSelectionStart() == previousSelectionStart) { | ||
key = BackspaceKeyValue; | ||
} else { | ||
key = String.valueOf(mEditText.getText().charAt(mEditText.getSelectionStart() - 1)); | ||
} | ||
queueKeyEventIfBatchEdit(key); | ||
return consumed; | ||
} | ||
|
||
@Override | ||
public boolean commitText(CharSequence text, int newCursorPosition) { | ||
mCommittedText = text.toString(); | ||
String key = text.toString(); | ||
if (key.equals("")) { | ||
key = BackspaceKeyValue; | ||
} | ||
queueKeyEventIfBatchEdit(key); | ||
|
||
return super.commitText(text, newCursorPosition); | ||
} | ||
|
||
@Override | ||
public boolean beginBatchEdit() { | ||
mPreviousSelectionStart = mEditText.getSelectionStart(); | ||
mPreviousSelectionEnd = mEditText.getSelectionEnd(); | ||
mCommittedText = null; | ||
mComposedText = null; | ||
return super.beginBatchEdit(); | ||
public boolean deleteSurroundingText(int beforeLength, int afterLength) { | ||
dispatchKeyEvent(BackspaceKeyValue); | ||
return super.deleteSurroundingText(beforeLength, afterLength); | ||
} | ||
|
||
// Called by SwiftKey when cursor at beginning of input when there is a delete. | ||
// Whereas stock Android Keyboard calls {@link InputConnection#deleteSurroundingText} | ||
@Override | ||
public boolean endBatchEdit() { | ||
String key; | ||
int selectionStart = mEditText.getSelectionStart(); | ||
if (mCommittedText == null) { | ||
if ((noPreviousSelection() && selectionStart < mPreviousSelectionStart) | ||
|| (!noPreviousSelection() && selectionStart == mPreviousSelectionStart) | ||
|| (mPreviousSelectionStart == 0 && selectionStart == 0)) { | ||
key = BackspaceKeyValue; | ||
} else { | ||
char enteredChar = mEditText.getText().charAt(selectionStart - 1); | ||
key = String.valueOf(enteredChar); | ||
} | ||
public boolean sendKeyEvent(KeyEvent event) { | ||
if(event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_DEL) { | ||
dispatchKeyEvent(BackspaceKeyValue); | ||
} | ||
else { | ||
key = mComposedText != null ? mComposedText : mCommittedText; | ||
} | ||
key = keyValueFromString(key); | ||
mEventDispatcher.dispatchEvent( | ||
new ReactTextInputKeyPressEvent( | ||
mEditText.getId(), | ||
key)); | ||
return super.endBatchEdit(); | ||
return super.sendKeyEvent(event); | ||
} | ||
|
||
private boolean noPreviousSelection() { | ||
return mPreviousSelectionStart == mPreviousSelectionEnd; | ||
private void queueKeyEventIfBatchEdit(String key) { | ||
if(mIsBatchEdit) { | ||
mKey = key; | ||
} else { | ||
dispatchKeyEvent(key); | ||
} | ||
} | ||
|
||
private String keyValueFromString(final String key) { | ||
String returnValue; | ||
switch (key) { | ||
case "": returnValue = BackspaceKeyValue; | ||
break; | ||
case NewLineRawValue: returnValue = EnterKeyValue; | ||
break; | ||
default: | ||
returnValue = key; | ||
break; | ||
private void dispatchKeyEvent(String key) { | ||
if (key.equals(NewLineRawValue)) { | ||
key = EnterKeyValue; | ||
} | ||
return returnValue; | ||
mEventDispatcher.dispatchEvent( | ||
new ReactTextInputKeyPressEvent( | ||
mEditText.getId(), | ||
key)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to have some high level comment here on what this class is for.
Also I think you didn't want to name this class this way ("InputInput"). As you need to change the name anyways I suggest that the class name include the word "Wrapper" (e.g. "ReactEditTextInputConnectionWrapper")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a more sensible name, thank you :P.