mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Focus text input on accessibility tap
Summary: There's an issue with TextInput on Android where if you have TalkBack enabled, double tapping doesn't focus the text input. It turns out this is because we ignore all focus events that aren't from JS in ReactEditText. This diff makes an exception for the accessibility click event. I think this should also fix https://github.com/facebook/react-native/issues/17624 Reviewed By: lunaleaps Differential Revision: D15818103 fbshipit-source-id: 354728b58f1023c4d44edd48337c8daa8ea15c0c
This commit is contained in:
committed by
Facebook Github Bot
parent
545b084cc8
commit
616864a2df
@@ -12,6 +12,7 @@ import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.SpannableStringBuilder;
|
||||
@@ -25,10 +26,13 @@ import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import androidx.core.view.AccessibilityDelegateCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.uimanager.UIManagerModule;
|
||||
@@ -60,8 +64,8 @@ public class ReactEditText extends EditText {
|
||||
// listeners and adding them back again after the text change is completed.
|
||||
protected boolean mIsSettingTextFromJS;
|
||||
// This component is controlled, so we want it to get focused only when JS ask it to do so.
|
||||
// Whenever android requests focus (which it does for random reasons), it will be ignored.
|
||||
private boolean mIsJSSettingFocus;
|
||||
// Whenever android requests focus, except for accessibility click, it will be ignored.
|
||||
private boolean mShouldAllowFocus;
|
||||
private int mDefaultGravityHorizontal;
|
||||
private int mDefaultGravityVertical;
|
||||
protected int mNativeEventCount;
|
||||
@@ -98,7 +102,7 @@ public class ReactEditText extends EditText {
|
||||
mNativeEventCount = 0;
|
||||
mMostRecentEventCount = 0;
|
||||
mIsSettingTextFromJS = false;
|
||||
mIsJSSettingFocus = false;
|
||||
mShouldAllowFocus = false;
|
||||
mBlurOnSubmit = null;
|
||||
mDisableFullscreen = false;
|
||||
mListeners = null;
|
||||
@@ -116,6 +120,19 @@ public class ReactEditText extends EditText {
|
||||
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
||||
ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegateCompat() {
|
||||
@Override
|
||||
public boolean performAccessibilityAction(View host, int action, Bundle args) {
|
||||
if (action == AccessibilityNodeInfo.ACTION_CLICK) {
|
||||
mShouldAllowFocus = true;
|
||||
requestFocus();
|
||||
mShouldAllowFocus = false;
|
||||
return true;
|
||||
}
|
||||
return super.performAccessibilityAction(host, action, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// After the text changes inside an EditText, TextView checks if a layout() has been requested.
|
||||
@@ -208,9 +225,11 @@ public class ReactEditText extends EditText {
|
||||
if (isFocused()) {
|
||||
return true;
|
||||
}
|
||||
if (!mIsJSSettingFocus) {
|
||||
|
||||
if (!mShouldAllowFocus) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setFocusableInTouchMode(true);
|
||||
boolean focused = super.requestFocus(direction, previouslyFocusedRect);
|
||||
if (getShowSoftInputOnFocus()) {
|
||||
@@ -361,9 +380,9 @@ public class ReactEditText extends EditText {
|
||||
|
||||
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||
public void requestFocusFromJS() {
|
||||
mIsJSSettingFocus = true;
|
||||
mShouldAllowFocus = true;
|
||||
requestFocus();
|
||||
mIsJSSettingFocus = false;
|
||||
mShouldAllowFocus = false;
|
||||
}
|
||||
|
||||
/* package */ void clearFocusFromJS() {
|
||||
|
||||
Reference in New Issue
Block a user