Skip to content

Commit 8582b75

Browse files
duom青源duom青源
duom青源
authored and
duom青源
committed
feat: update props
1 parent 8f72e4f commit 8582b75

File tree

8 files changed

+208
-61
lines changed

8 files changed

+208
-61
lines changed

android/src/main/java/com/variabletextinput/VariableTextInputViewManager.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import android.graphics.drawable.Drawable;
55
import android.os.Build;
66
import android.text.InputFilter;
7+
import android.text.InputType;
78
import android.text.Layout;
89
import android.util.Log;
910
import android.view.Gravity;
@@ -201,6 +202,24 @@ public void setSelectionColor(EditText view, @Nullable Integer color) {
201202
view.setHighlightColor(color);
202203
}
203204
}
205+
@ReactProp(name = "disableFullscreenUI", defaultBoolean = false)
206+
public void setDisableFullscreenUI(VariableTextInput view, boolean disableFullscreenUI) {
207+
view.setDisableFullscreenUI(disableFullscreenUI);
208+
}
209+
@ReactProp(name = "returnKeyType")
210+
public void setReturnKeyType(VariableTextInput view, String returnKeyType) {
211+
view.setReturnKeyType(returnKeyType);
212+
}
213+
private static final int IME_ACTION_ID = 0x670;
214+
215+
@ReactProp(name = "returnKeyLabel")
216+
public void setReturnKeyLabel(VariableTextInput view, String returnKeyLabel) {
217+
view.setImeActionLabel(returnKeyLabel, IME_ACTION_ID);
218+
}
219+
@ReactProp(name = "submitBehavior")
220+
public void setSubmitBehavior(VariableTextInput view, @Nullable String submitBehavior) {
221+
view.setSubmitBehavior(submitBehavior);
222+
}
204223
@ReactProp(name = "underlineColorAndroid", customType = "Color")
205224
public void setUnderlineColor(VariableTextInput view, @Nullable Integer underlineColor) {
206225
// Drawable.mutate() can sometimes crash due to an AOSP bug:
@@ -235,6 +254,14 @@ public void setUnderlineColor(VariableTextInput view, @Nullable Integer underlin
235254
}
236255
}
237256
}
257+
@ReactProp(name = "onSelectionChange", defaultBoolean = false)
258+
public void setOnSelectionChange(final VariableTextInput view, boolean onSelectionChange) {
259+
if (onSelectionChange) {
260+
view.setSelectionWatcher(new ReactSelectionWatcher(view));
261+
} else {
262+
view.setSelectionWatcher(null);
263+
}
264+
}
238265
@ReactProp(name = "keyboardType")
239266
public void setKeyboardType(VariableTextInput view, String keyboardType) {
240267
switch (keyboardType) {
@@ -324,6 +351,6 @@ public Map<String, Object> getConstants() {
324351
"onAndroidChange",
325352
MapBuilder.of("registrationName", "onAndroidChange")
326353
).put( "onAndroidContentSizeChange",
327-
MapBuilder.of("registrationName", "onAndroidContentSizeChange")).build();
354+
MapBuilder.of("registrationName", "onAndroidContentSizeChange")).put("onAndroidSubmitEditing",MapBuilder.of("registrationName","onAndroidSubmitEditing")).build();
328355
}
329356
}

android/src/main/java/com/variabletextinput/view/VariableEditText.java

+35
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
import android.content.Context;
44
import android.util.AttributeSet;
55

6+
import androidx.annotation.Nullable;
67
import androidx.appcompat.widget.AppCompatEditText;
78

89
public class VariableEditText extends AppCompatEditText {
910

1011
private OnMenuItemCallBack mOnMenuItemCallBack;
1112

13+
private @Nullable
14+
String mSubmitBehavior = null;
15+
1216
public VariableEditText(Context context) {
1317
super(context);
1418
}
@@ -20,7 +24,38 @@ public VariableEditText(Context context, AttributeSet attrs) {
2024
public VariableEditText(Context context, AttributeSet attrs, int defStyleAttr) {
2125
super(context, attrs, defStyleAttr);
2226
}
27+
public boolean shouldSubmitOnReturn() {
28+
String submitBehavior = getSubmitBehavior();
29+
boolean shouldSubmit;
30+
31+
// Default shouldSubmit
32+
if (submitBehavior == null) {
33+
shouldSubmit = false;
34+
} else {
35+
shouldSubmit = submitBehavior.equals("submit") || submitBehavior.equals("blurAndSubmit");
36+
}
37+
38+
return shouldSubmit;
39+
}
40+
public void setSubmitBehavior(String submitBehavior) {
41+
mSubmitBehavior = submitBehavior;
42+
}
43+
public boolean shouldBlurOnReturn() {
44+
String submitBehavior = getSubmitBehavior();
45+
boolean shouldBlur;
46+
47+
// Default shouldBlur
48+
if (submitBehavior == null) {
49+
shouldBlur = false;
50+
} else {
51+
shouldBlur = submitBehavior.equals("blurAndSubmit");
52+
}
2353

54+
return shouldBlur;
55+
}
56+
public String getSubmitBehavior() {
57+
return mSubmitBehavior;
58+
}
2459
@Override
2560
public boolean isLayoutRequested() {
2661
// If we are watching and updating container height based on content size

android/src/main/java/com/variabletextinput/view/VariableTextInput.java

+108-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
import android.util.Log;
2222
import android.view.ActionMode;
2323
import android.view.Gravity;
24+
import android.view.KeyEvent;
2425
import android.view.Menu;
2526
import android.view.MenuItem;
27+
import android.view.inputmethod.EditorInfo;
2628
import android.view.inputmethod.InputMethodManager;
2729
import android.widget.LinearLayout;
2830
import android.widget.ScrollView;
@@ -35,6 +37,7 @@
3537
import com.facebook.react.bridge.ReadableMap;
3638
import com.facebook.react.bridge.WritableMap;
3739
import com.facebook.react.uimanager.Spacing;
40+
import com.facebook.react.uimanager.events.EventDispatcher;
3841
import com.facebook.react.uimanager.events.RCTEventEmitter;
3942
import com.facebook.react.views.text.ReactFontManager;
4043
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
@@ -66,6 +69,8 @@ public class VariableTextInput extends LinearLayout {
6669
private SpannableString mSpannableString;
6770
private Editable mEditable;
6871
private ReactViewBackgroundDrawable reactViewBackgroundDrawable;
72+
private @Nullable String mReturnKeyType;
73+
private boolean mDisableFullscreen;
6974
private static final InputFilter[] EMPTY_FILTERS = new InputFilter[0];
7075
public VariableTextInput(Context context) {
7176
super(context);
@@ -80,6 +85,8 @@ public VariableTextInput(Context context) {
8085
editText.setInputType(editText.getInputType() | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
8186
| InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
8287
editText.setPadding(0, 0, 0, 0);
88+
editText.setImeOptions(EditorInfo.IME_ACTION_NONE);
89+
mDisableFullscreen = false;
8390
// This was used in conjunction with setting raw input type for selecting lock
8491
// notes.
8592
// However, it causes the keyboard to not come up for editing existing notes.
@@ -198,6 +205,55 @@ public void onPaste() {
198205
}
199206
}
200207
});
208+
editText.setOnEditorActionListener(
209+
new TextView.OnEditorActionListener() {
210+
@Override
211+
public boolean onEditorAction(TextView v, int actionId, KeyEvent keyEvent) {
212+
if ((actionId & EditorInfo.IME_MASK_ACTION) != 0 || actionId == EditorInfo.IME_NULL) {
213+
boolean isMultiline = true;
214+
215+
boolean shouldSubmit = editText.shouldSubmitOnReturn();
216+
boolean shouldBlur = editText.shouldBlurOnReturn();
217+
// Motivation:
218+
// * shouldSubmit => Clear focus; prevent default behavior (return true);
219+
// * shouldBlur => Submit; prevent default behavior (return true);
220+
// * !shouldBlur && !shouldSubmit && isMultiline => Perform default behavior (return
221+
// false);
222+
// * !shouldBlur && !shouldSubmit && !isMultiline => Prevent default behavior (return
223+
// true);
224+
if (shouldSubmit) {
225+
WritableMap event = Arguments.createMap();
226+
event.putString("text", editText.getText().toString());
227+
final Context context = getContext();
228+
if (context instanceof ReactContext) {
229+
((ReactContext) context).getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "onAndroidSubmitEditing", event);
230+
}
231+
}
232+
233+
if (shouldBlur) {
234+
editText.clearFocus();
235+
}
236+
237+
// Prevent default behavior except when we want it to insert a newline.
238+
if (shouldBlur || shouldSubmit || !isMultiline) {
239+
return true;
240+
}
241+
242+
// If we've reached this point, it means that the TextInput has 'submitBehavior' set
243+
// nullish and 'multiline' set to true. But it's still possible to get IME_ACTION_NEXT
244+
// and IME_ACTION_PREVIOUS here in case if 'disableFullscreenUI' is false and Android
245+
// decides to render this EditText in the full screen mode (when a phone has the
246+
// landscape orientation for example). The full screen EditText also renders an action
247+
// button specified by the 'returnKeyType' prop. We have to prevent Android from
248+
// requesting focus from the next/previous focusable view since it must only be
249+
// controlled from JS.
250+
return actionId == EditorInfo.IME_ACTION_NEXT
251+
|| actionId == EditorInfo.IME_ACTION_PREVIOUS;
252+
}
253+
254+
return true;
255+
}
256+
});
201257
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
202258
editText.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
203259
@Override
@@ -377,7 +433,9 @@ public void setBorderWidth(int position, float width) {
377433
public void setBorderColor(int position, float color, float alpha) {
378434
reactViewBackgroundDrawable.setBorderColor(position, color, alpha);
379435
}
380-
436+
public void setSubmitBehavior(String submitBehavior) {
437+
editText.setSubmitBehavior(submitBehavior);
438+
}
381439
public int getBorderColor(int position) {
382440
return reactViewBackgroundDrawable.getBorderColor(position);
383441
}
@@ -472,8 +530,55 @@ public void setPlaceholder(String placeholder) {
472530
public void setPlaceholderColor(int placeholderColor){
473531
editText.setHintTextColor(placeholderColor);
474532
}
475-
public void setUnderLineColorAndroid(Integer color) {
476-
editText.setBackgroundTintList(ColorStateList.valueOf(color));
533+
public void setReturnKeyType(String returnKeyType) {
534+
mReturnKeyType = returnKeyType;
535+
updateImeOptions();
536+
}
537+
private void updateImeOptions() {
538+
// Default to IME_ACTION_DONE
539+
int returnKeyFlag = EditorInfo.IME_ACTION_DONE;
540+
if (mReturnKeyType != null) {
541+
switch (mReturnKeyType) {
542+
case "go":
543+
returnKeyFlag = EditorInfo.IME_ACTION_GO;
544+
break;
545+
case "next":
546+
returnKeyFlag = EditorInfo.IME_ACTION_NEXT;
547+
break;
548+
case "none":
549+
returnKeyFlag = EditorInfo.IME_ACTION_NONE;
550+
break;
551+
case "previous":
552+
returnKeyFlag = EditorInfo.IME_ACTION_PREVIOUS;
553+
break;
554+
case "search":
555+
returnKeyFlag = EditorInfo.IME_ACTION_SEARCH;
556+
break;
557+
case "send":
558+
returnKeyFlag = EditorInfo.IME_ACTION_SEND;
559+
break;
560+
case "done":
561+
returnKeyFlag = EditorInfo.IME_ACTION_DONE;
562+
break;
563+
}
564+
}
565+
566+
if (mDisableFullscreen) {
567+
setImeOptions(returnKeyFlag | EditorInfo.IME_FLAG_NO_FULLSCREEN);
568+
} else {
569+
setImeOptions(returnKeyFlag);
570+
}
571+
}
572+
public void setImeActionLabel(String returnKeyLabel,int imID){
573+
editText.setImeActionLabel(returnKeyLabel,imID);
574+
}
575+
public void setDisableFullscreenUI(boolean disableFullscreenUI) {
576+
mDisableFullscreen = disableFullscreenUI;
577+
updateImeOptions();
578+
}
579+
580+
public boolean getDisableFullscreenUI() {
581+
return mDisableFullscreen;
477582
}
478583
public void setFontSize(Integer fontSize) {
479584
editText.setTextSize(fontSize);

example/src/App.tsx

+6-57
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
ImageResolvedAssetSource,
88
Image,
99
View,
10-
TextInput,
1110
} from 'react-native';
1211
import {
1312
IATTextViewBase,
@@ -89,6 +88,9 @@ export const App = () => {
8988
const focus = () => {
9089
inPutRef.current?.focus();
9190
};
91+
const sub = (e: any) => {
92+
console.log('rrrrr===>', e);
93+
};
9294
return (
9395
<ScrollView contentContainerStyle={styles.container}>
9496
<VariableTextInputView
@@ -98,39 +100,9 @@ export const App = () => {
98100
placeholder={'测试测试测试'}
99101
placeholderTextColor={'#fff'}
100102
underlineColorAndroid={'rgba(0,0,0,0)'}
101-
/>
102-
<TextInput
103-
multiline={true}
104-
placeholder="测试测试"
105-
style={{
106-
height: 50,
107-
backgroundColor: 'red',
108-
width: '100%',
109-
borderRadius: 5,
110-
borderTopColor: 'red',
111-
borderTopEndRadius: 5,
112-
borderTopLeftRadius: 5,
113-
borderTopRightRadius: 5,
114-
borderTopStartRadius: 5,
115-
borderTopWidth: 1,
116-
borderLeftColor: 'red',
117-
borderLeftWidth: 1,
118-
borderBottomColor: 'red',
119-
borderBottomEndRadius: 5,
120-
borderBottomLeftRadius: 5,
121-
borderBottomRightRadius: 5,
122-
borderBottomStartRadius: 5,
123-
borderBottomWidth: 1,
124-
borderColor: 'red',
125-
borderEndColor: 'red',
126-
borderEndWidth: 1,
127-
borderRightColor: 'red',
128-
borderRightWidth: 1,
129-
borderStartColor: 'red',
130-
borderStartWidth: 1,
131-
borderWidth: 1,
132-
borderStyle: 'dashed',
133-
}}
103+
blurOnSubmit={true}
104+
onSubmitEditing={sub}
105+
keyboardAppearance={'dark'}
134106
/>
135107
<View style={{ flexDirection: 'row', marginTop: 40 }}>
136108
<TouchableOpacity onPress={blur} style={{ marginLeft: 20 }}>
@@ -179,28 +151,5 @@ const styles = StyleSheet.create({
179151
width: '100%',
180152
minHeight: 100,
181153
borderRadius: 5,
182-
borderTopColor: 'red',
183-
borderTopEndRadius: 5,
184-
borderTopLeftRadius: 5,
185-
borderTopRightRadius: 5,
186-
borderTopStartRadius: 5,
187-
borderTopWidth: 1,
188-
borderLeftColor: 'red',
189-
borderLeftWidth: 1,
190-
borderBottomColor: 'red',
191-
borderBottomEndRadius: 5,
192-
borderBottomLeftRadius: 5,
193-
borderBottomRightRadius: 5,
194-
borderBottomStartRadius: 5,
195-
borderBottomWidth: 1,
196-
borderColor: 'red',
197-
borderEndColor: 'red',
198-
borderEndWidth: 1,
199-
borderRightColor: 'red',
200-
borderRightWidth: 1,
201-
borderStartColor: 'red',
202-
borderStartWidth: 1,
203-
borderWidth: 1,
204-
borderStyle: 'dashed',
205154
},
206155
});

ios/VariableTextInput.h

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
4444
@property(assign, nonatomic, getter=isSupport) BOOL bSupport;
4545
@property(nonatomic, copy) RCTBubblingEventBlock onChange;
4646
@property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange;
47+
@property(nonatomic, copy) RCTBubblingEventBlock onSubmitEditing;
4748
@property(nonatomic, copy, nullable) RCTDirectEventBlock onTextInput;
4849
@property(nonatomic, strong) NSDictionary *defultTypingAttributes;
4950
@property(nonatomic, strong) NSArray *tags;
@@ -57,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
5758
@property (nonatomic, assign) CGFloat paddingHorizontal;
5859
@property (nonatomic, assign) CGFloat paddingVertical;
5960
@property (nonatomic, assign) CGFloat padding;
61+
@property (nonatomic, assign) BOOL blurOnSubmit;
6062
- (void)setPlaceholderVisibleForText:(NSString *)str;
6163
- (NSString *)getStrContentInRange:(NSRange)range;
6264
@end

ios/VariableTextInput.m

+12
Original file line numberDiff line numberDiff line change
@@ -620,4 +620,16 @@ - (void)setPaddingVertical:(CGFloat)paddingVertical
620620
UIEdgeInsets insets = self.textContainerInset;
621621
[self setPaddingTop:paddingVertical left:insets.left bottom:paddingVertical right:insets.right];
622622
}
623+
- (BOOL)textInputShouldReturn
624+
{
625+
// We send `submit` event here, in `textInputShouldReturn`
626+
// (not in `textInputDidReturn)`, because of semantic of the event:
627+
// `onSubmitEditing` is called when "Submit" button
628+
// (the blue key on onscreen keyboard) did pressed
629+
// (no connection to any specific "submitting" process).
630+
if (self.onSubmitEditing) {
631+
self.onSubmitEditing(@{@"text": [self.textStorage getPlainString]});
632+
}
633+
return _blurOnSubmit;
634+
}
623635
@end

0 commit comments

Comments
 (0)