Skip to content

Commit 939904f

Browse files
duom青源duom青源
duom青源
authored and
duom青源
committed
feat: style border update
1 parent 8471328 commit 939904f

File tree

6 files changed

+339
-12
lines changed

6 files changed

+339
-12
lines changed

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

+117-5
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
package com.variabletextinput;
2+
3+
import android.graphics.PorterDuff;
4+
import android.graphics.drawable.Drawable;
5+
import android.os.Build;
6+
import android.text.InputFilter;
7+
import android.text.Layout;
28
import android.util.Log;
9+
import android.view.Gravity;
310
import android.view.inputmethod.EditorInfo;
411
import android.widget.EditText;
512
import androidx.annotation.NonNull;
613
import androidx.annotation.Nullable;
14+
15+
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
716
import com.facebook.react.bridge.ReactApplicationContext;
817
import com.facebook.react.bridge.ReadableArray;
918
import com.facebook.react.common.MapBuilder;
19+
import com.facebook.react.uimanager.PixelUtil;
1020
import com.facebook.react.uimanager.SimpleViewManager;
1121
import com.facebook.react.uimanager.Spacing;
1222
import com.facebook.react.uimanager.ThemedReactContext;
1323
import com.facebook.react.uimanager.ViewProps;
1424
import com.facebook.react.uimanager.annotations.ReactProp;
1525
import com.facebook.react.uimanager.annotations.ReactPropGroup;
26+
import com.facebook.yoga.YogaConstants;
1627
import com.variabletextinput.view.VariableTextInput;
1728

1829
import java.util.HashMap;
30+
import java.util.LinkedList;
1931
import java.util.Map;
2032
public class VariableTextInputViewManager extends SimpleViewManager<VariableTextInput> {
2133
private enum RNTONATIVEMETHOD {
@@ -35,6 +47,9 @@ public String getName(){
3547
private static final int[] PADDING_TYPES = {
3648
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
3749
};
50+
private static final int[] SPACING_TYPES = {
51+
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
52+
};
3853
public static final String REACT_CLASS = "VariableTextInputView";
3954
ReactApplicationContext mCallerContext;
4055
VariableTextInput editText;
@@ -63,6 +78,12 @@ public void setColor(VariableTextInput view, @Nullable Integer color) {
6378
view.setTextColor(color);
6479
}
6580
}
81+
@ReactProp(name = ViewProps.BACKGROUND_COLOR, customType = "Color")
82+
public void setBackGroundColor(VariableTextInput view, @Nullable Integer color) {
83+
if (color != null) {
84+
view.setBackGroundColor(color);
85+
}
86+
}
6687
@ReactProp(name = ViewProps.FONT_SIZE, customType = "FontColor")
6788
public void setFontSize(VariableTextInput view, @Nullable Integer fontSize) {
6889
if (fontSize != null) {
@@ -81,7 +102,10 @@ public void setSelectionColor(VariableTextInput view, @Nullable Integer color) {
81102
view.setHighlightColor(color);
82103
}
83104
}
84-
105+
@ReactProp(name = "maxLength")
106+
public void setMaxLength(VariableTextInput view, @Nullable Integer maxLength) {
107+
view.setMaxLength(maxLength);
108+
}
85109
@ReactProp(name = "handlesColor", customType = "Color")
86110
public void setHandlesColor(VariableTextInput view, @Nullable Integer color) {
87111
if (color != null) {
@@ -92,9 +116,63 @@ public void setHandlesColor(VariableTextInput view, @Nullable Integer color) {
92116
@ReactPropGroup(names = {
93117
"padding", "paddingLeft", "paddingRight", "paddingTop", "paddingBottom"
94118
}, customType = "String")
95-
public void setBorderColor(VariableTextInput view, int index, Integer padding) {
119+
public void setPadding(VariableTextInput view, int index, Integer padding) {
96120
view.setContentPadding(PADDING_TYPES[index], padding);
97121
}
122+
@ReactPropGroup(
123+
names = {
124+
ViewProps.BORDER_RADIUS,
125+
ViewProps.BORDER_TOP_LEFT_RADIUS,
126+
ViewProps.BORDER_TOP_RIGHT_RADIUS,
127+
ViewProps.BORDER_BOTTOM_RIGHT_RADIUS,
128+
ViewProps.BORDER_BOTTOM_LEFT_RADIUS
129+
},
130+
defaultFloat = YogaConstants.UNDEFINED)
131+
public void setBorderRadius(VariableTextInput view, int index, float borderRadius) {
132+
if (!YogaConstants.isUndefined(borderRadius)) {
133+
borderRadius = PixelUtil.toPixelFromDIP(borderRadius);
134+
}
135+
136+
if (index == 0) {
137+
view.setBorderRadius(borderRadius);
138+
} else {
139+
view.setBorderRadius(borderRadius, index - 1);
140+
}
141+
}
142+
@ReactPropGroup(
143+
names = {
144+
ViewProps.BORDER_WIDTH,
145+
ViewProps.BORDER_LEFT_WIDTH,
146+
ViewProps.BORDER_RIGHT_WIDTH,
147+
ViewProps.BORDER_TOP_WIDTH,
148+
ViewProps.BORDER_BOTTOM_WIDTH,
149+
},
150+
defaultFloat = YogaConstants.UNDEFINED)
151+
public void setBorderWidth(VariableTextInput view, int index, float width) {
152+
if (!YogaConstants.isUndefined(width)) {
153+
width = PixelUtil.toPixelFromDIP(width);
154+
}
155+
view.setBorderWidth(SPACING_TYPES[index], width);
156+
}
157+
@ReactPropGroup(
158+
names = {
159+
"borderColor",
160+
"borderLeftColor",
161+
"borderRightColor",
162+
"borderTopColor",
163+
"borderBottomColor"
164+
},
165+
customType = "Color")
166+
public void setBorderColor(VariableTextInput view, int index, Integer color) {
167+
float rgbComponent =
168+
color == null ? YogaConstants.UNDEFINED : (float) ((int) color & 0x00FFFFFF);
169+
float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int) color >>> 24);
170+
view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent);
171+
}
172+
@ReactProp(name = "borderStyle")
173+
public void setBorderStyle(VariableTextInput view, @Nullable String borderStyle) {
174+
view.setBorderStyle(borderStyle);
175+
}
98176
@ReactProp(name = "autoFocus")
99177
public void setAutoFocus(VariableTextInput view, boolean autoFocus) {
100178
view.setAutoFocus(autoFocus);
@@ -113,15 +191,49 @@ public void blur(VariableTextInput view) {
113191
public void setPlaceholder(VariableTextInput view, String placeholder){
114192
view.setPlaceholder(placeholder);
115193
}
194+
@ReactProp(name="placeholderTextColor",customType = "Color")
195+
public void setPlaceholderTextColor(VariableTextInput view, @Nullable Integer placeholderColor){
196+
view.setPlaceholderColor(placeholderColor);
197+
}
116198
@ReactProp(name = "selectionColor", customType = "Color")
117199
public void setSelectionColor(EditText view, @Nullable Integer color) {
118200
if (color != null) {
119201
view.setHighlightColor(color);
120202
}
121203
}
122-
@ReactProp(name="underlineColorAndroid",customType ="Color" )
123-
public void setUnderLineColorAndroid(VariableTextInput view,@Nullable Integer color){
124-
view.setUnderLineColorAndroid(color);
204+
@ReactProp(name = "underlineColorAndroid", customType = "Color")
205+
public void setUnderlineColor(VariableTextInput view, @Nullable Integer underlineColor) {
206+
// Drawable.mutate() can sometimes crash due to an AOSP bug:
207+
// See https://code.google.com/p/android/issues/detail?id=191754 for more info
208+
Drawable background = view.getBackground();
209+
Drawable drawableToMutate = background;
210+
211+
if (background == null) {
212+
return;
213+
}
214+
215+
if (background.getConstantState() != null) {
216+
try {
217+
drawableToMutate = background.mutate();
218+
} catch (NullPointerException e) {
219+
// FLog.e(TAG, "NullPointerException when setting underlineColorAndroid for TextInput", e);
220+
}
221+
}
222+
223+
if (underlineColor == null) {
224+
drawableToMutate.clearColorFilter();
225+
} else {
226+
// fixes underlineColor transparent not working on API 21
227+
// re-sets the TextInput underlineColor https://bit.ly/3M4alr6
228+
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
229+
int bottomBorderColor = view.getBorderColor(Spacing.BOTTOM);
230+
setBorderColor(view, Spacing.START, underlineColor);
231+
drawableToMutate.setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
232+
setBorderColor(view, Spacing.START, bottomBorderColor);
233+
} else {
234+
drawableToMutate.setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
235+
}
236+
}
125237
}
126238
@ReactProp(name = "keyboardType")
127239
public void setKeyboardType(VariableTextInput view, String keyboardType) {

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

+81-6
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
import android.graphics.PorterDuff;
1111
import android.graphics.Typeface;
1212
import android.graphics.drawable.Drawable;
13+
import android.graphics.drawable.ShapeDrawable;
1314
import android.net.Uri;
1415
import android.os.Build;
1516
import android.text.Editable;
17+
import android.text.InputFilter;
1618
import android.text.SpannableString;
1719
import android.text.Spanned;
1820
import android.text.TextUtils;
@@ -37,6 +39,8 @@
3739
import com.facebook.react.uimanager.Spacing;
3840
import com.facebook.react.uimanager.events.RCTEventEmitter;
3941
import com.facebook.react.views.text.ReactFontManager;
42+
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
43+
import com.facebook.react.views.view.ReactViewBackgroundManager;
4044
import com.variabletextinput.R;
4145
import com.variabletextinput.bean.RichTextBean;
4246
import com.variabletextinput.util.ActivityConst;
@@ -47,6 +51,7 @@
4751
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
4852

4953
import androidx.annotation.NonNull;
54+
import androidx.annotation.Nullable;
5055
import androidx.core.content.ContextCompat;
5156

5257
import java.io.IOException;
@@ -55,6 +60,7 @@
5560
import java.net.HttpURLConnection;
5661
import java.net.URI;
5762
import java.net.URL;
63+
import java.util.LinkedList;
5864

5965
public class VariableTextInput extends LinearLayout {
6066
private VariableEditText editText;
@@ -64,7 +70,8 @@ public class VariableTextInput extends LinearLayout {
6470
private Context mContext;
6571
private SpannableString mSpannableString;
6672
private Editable mEditable;
67-
73+
private ReactViewBackgroundDrawable reactViewBackgroundDrawable;
74+
private static final InputFilter[] EMPTY_FILTERS = new InputFilter[0];
6875
public VariableTextInput(Context context) {
6976
super(context);
7077
this.mContext = context;
@@ -84,6 +91,11 @@ public VariableTextInput(Context context) {
8491
// Tested while offline using brand new installation on Android 6 emulator, but
8592
// a user with Android 7 also reported it.
8693
// editText.setTextIsSelectable(true);
94+
// 创建 ShapeDrawable 对象,方便设置圆角和边框样式
95+
// shapeDrawable = new ShapeDrawable();
96+
// editText.setBackground(shapeDrawable);
97+
reactViewBackgroundDrawable = new ReactViewBackgroundDrawable(context);
98+
editText.setBackground(reactViewBackgroundDrawable);
8799
scrollView.addView(editText);
88100
this.addView(scrollView);
89101
// 添加 TextWatcher 监听器
@@ -223,7 +235,6 @@ public void onDestroyActionMode(ActionMode actionMode) {
223235
});
224236
}
225237
}
226-
227238
private Editable handleSelectData() {
228239
if (editText.getText() != null) {
229240
mEditable = Editable.Factory.getInstance()
@@ -267,7 +278,6 @@ public int pxToDp(int px) {
267278
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
268279
super.onLayout(changed, left, top, right, bottom);
269280
}
270-
271281
public void setText(String text) {
272282
// Fix for issue where first character typed does not trigger save event.
273283
// setText is called with an empty string originally as soon as the text view is
@@ -318,6 +328,10 @@ public void setEditable(boolean editable) {
318328

319329
}
320330

331+
public void setBackGroundColor(Integer color){
332+
reactViewBackgroundDrawable.setColor(color);
333+
}
334+
321335
public void focus() {
322336
editText.requestFocus();
323337
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -361,7 +375,29 @@ public void setContentPadding(int position, Integer padding) {
361375
editText.setPadding(editText.getPaddingLeft(), editText.getTotalPaddingTop(), editText.getPaddingRight(), pixels);
362376
}
363377
}
378+
public void setBorderWidth(int position, float width) {
379+
reactViewBackgroundDrawable.setBorderWidth(position, width);
380+
}
381+
382+
public void setBorderColor(int position, float color, float alpha) {
383+
reactViewBackgroundDrawable.setBorderColor(position, color, alpha);
384+
}
364385

386+
public int getBorderColor(int position) {
387+
return reactViewBackgroundDrawable.getBorderColor(position);
388+
}
389+
390+
public void setBorderRadius(float borderRadius) {
391+
reactViewBackgroundDrawable.setRadius(borderRadius);
392+
}
393+
394+
public void setBorderRadius(float borderRadius, int position) {
395+
reactViewBackgroundDrawable.setRadius(borderRadius, position);
396+
}
397+
398+
public void setBorderStyle(@Nullable String style) {
399+
reactViewBackgroundDrawable.setBorderStyle(style);
400+
}
365401
public void setTextColor(Integer color) {
366402
editText.setTextColor(color);
367403
}
@@ -438,15 +474,55 @@ public void setHandlesColor(int color) {
438474
public void setPlaceholder(String placeholder) {
439475
editText.setHint(placeholder);
440476
}
441-
477+
public void setPlaceholderColor(int placeholderColor){
478+
editText.setHintTextColor(placeholderColor);
479+
}
442480
public void setUnderLineColorAndroid(Integer color) {
443481
editText.setBackgroundTintList(ColorStateList.valueOf(color));
444482
}
445-
446483
public void setFontSize(Integer fontSize) {
447484
editText.setTextSize(fontSize);
448485
}
486+
public void setMaxLength(@Nullable Integer maxLength){
487+
InputFilter[] currentFilters = editText.getFilters();
488+
InputFilter[] newFilters = EMPTY_FILTERS;
489+
490+
if (maxLength == null) {
491+
if (currentFilters.length > 0) {
492+
LinkedList<InputFilter> list = new LinkedList<>();
493+
for (int i = 0; i < currentFilters.length; i++) {
494+
if (!(currentFilters[i] instanceof InputFilter.LengthFilter)) {
495+
list.add(currentFilters[i]);
496+
}
497+
}
498+
if (!list.isEmpty()) {
499+
newFilters = (InputFilter[]) list.toArray(new InputFilter[list.size()]);
500+
}
501+
}
502+
} else {
503+
if (currentFilters.length > 0) {
504+
newFilters = currentFilters;
505+
boolean replaced = false;
506+
for (int i = 0; i < currentFilters.length; i++) {
507+
if (currentFilters[i] instanceof InputFilter.LengthFilter) {
508+
currentFilters[i] = new InputFilter.LengthFilter(maxLength);
509+
replaced = true;
510+
}
511+
}
512+
if (!replaced) {
513+
newFilters = new InputFilter[currentFilters.length + 1];
514+
System.arraycopy(currentFilters, 0, newFilters, 0, currentFilters.length);
515+
currentFilters[currentFilters.length] = new InputFilter.LengthFilter(maxLength);
516+
}
517+
} else {
518+
newFilters = new InputFilter[1];
519+
newFilters[0] = new InputFilter.LengthFilter(maxLength);
520+
}
521+
}
449522

523+
editText.setFilters(newFilters);
524+
525+
}
450526
public void setFontFamily(String fontFamily) {
451527
int style = Typeface.NORMAL;
452528
if (editText.getTypeface() != null) {
@@ -456,7 +532,6 @@ public void setFontFamily(String fontFamily) {
456532
editText.getContext().getAssets());
457533
editText.setTypeface(newTypeFace);
458534
}
459-
460535
public void handleRichText(ReadableArray args) {
461536
if (args != null && args.size() > 0) {
462537
for (int i = 0; i < args.size(); i++) {

0 commit comments

Comments
 (0)