Convert remaining viewmanager to @ReactProp.

Differential Revision: D2481816

committer: Service User <svcscm@fb.com>
This commit is contained in:
Krzysztof Magiera 2015-09-25 14:43:28 -07:00 коммит произвёл facebook-github-bot-7
Родитель 0fb3d8de83
Коммит 656126a2f1
12 изменённых файлов: 345 добавлений и 408 удалений

Просмотреть файл

@ -54,8 +54,8 @@ import com.facebook.react.uimanager.events.NativeGestureUtil;
setDrawerProperties();
}
/* package */ void setDrawerWidth(int drawerWidth) {
mDrawerWidth = (int) PixelUtil.toPixelFromDIP((float) drawerWidth);
/* package */ void setDrawerWidth(int drawerWidthInPx) {
mDrawerWidth = drawerWidthInPx;
setDrawerProperties();
}

Просмотреть файл

@ -21,10 +21,10 @@ import android.view.View;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.drawer.events.DrawerClosedEvent;
@ -42,11 +42,6 @@ public class ReactDrawerLayoutManager extends ViewGroupManager<ReactDrawerLayout
public static final int OPEN_DRAWER = 1;
public static final int CLOSE_DRAWER = 2;
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_DRAWER_POSITION = "drawerPosition";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_DRAWER_WIDTH = "drawerWidth";
@Override
public String getName() {
return REACT_CLASS;
@ -65,22 +60,20 @@ public class ReactDrawerLayoutManager extends ViewGroupManager<ReactDrawerLayout
return new ReactDrawerLayout(context);
}
@Override
public void updateView(ReactDrawerLayout view, CatalystStylesDiffMap props) {
super.updateView(view, props);
if (props.hasKey(PROP_DRAWER_POSITION)) {
int drawerPosition = props.getInt(PROP_DRAWER_POSITION, -1);
if (Gravity.START == drawerPosition || Gravity.END == drawerPosition) {
view.setDrawerPosition(drawerPosition);
} else {
throw new JSApplicationIllegalArgumentException("Unknown drawerPosition " + drawerPosition);
}
@ReactProp(name = "drawerPosition", defaultInt = Gravity.START)
public void setDrawerPosition(ReactDrawerLayout view, int drawerPosition) {
if (Gravity.START == drawerPosition || Gravity.END == drawerPosition) {
view.setDrawerPosition(drawerPosition);
} else {
throw new JSApplicationIllegalArgumentException("Unknown drawerPosition " + drawerPosition);
}
}
if (props.hasKey(PROP_DRAWER_WIDTH)) {
view.setDrawerWidth(props.getInt(PROP_DRAWER_WIDTH, ReactDrawerLayout.DEFAULT_DRAWER_WIDTH));
}
@ReactProp(name = "drawerWidth", defaultFloat = Float.NaN)
public void getDrawerWidth(ReactDrawerLayout view, float width) {
int widthInPx = Float.isNaN(width) ?
ReactDrawerLayout.DEFAULT_DRAWER_WIDTH : Math.round(PixelUtil.toPixelFromDIP(width));
view.setDrawerWidth(widthInPx);
}
@Override

Просмотреть файл

@ -15,10 +15,9 @@ import android.graphics.Color;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.AbstractDraweeControllerBuilder;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewProps;
public class ReactImageManager extends SimpleViewManager<ReactImageView> {
@ -30,15 +29,6 @@ public class ReactImageManager extends SimpleViewManager<ReactImageView> {
return REACT_CLASS;
}
// In JS this is Image.props.source.uri
@UIProp(UIProp.Type.STRING)
public static final String PROP_SRC = "src";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_BORDER_RADIUS = "borderRadius";
@UIProp(UIProp.Type.STRING)
public static final String PROP_RESIZE_MODE = ViewProps.RESIZE_MODE;
private static final String PROP_TINT_COLOR = "tintColor";
private final @Nullable AbstractDraweeControllerBuilder mDraweeControllerBuilder;
private final @Nullable Object mCallerContext;
@ -63,27 +53,34 @@ public class ReactImageManager extends SimpleViewManager<ReactImageView> {
mCallerContext);
}
@Override
public void updateView(final ReactImageView view, final CatalystStylesDiffMap props) {
super.updateView(view, props);
// In JS this is Image.props.source.uri
@ReactProp(name = "src")
public void setSource(ReactImageView view, @Nullable String source) {
view.setSource(source);
}
if (props.hasKey(PROP_RESIZE_MODE)) {
view.setScaleType(ImageResizeMode.toScaleType(props.getString(PROP_RESIZE_MODE)));
}
if (props.hasKey(PROP_SRC)) {
view.setSource(props.getString(PROP_SRC));
}
if (props.hasKey(PROP_BORDER_RADIUS)) {
view.setBorderRadius(props.getFloat(PROP_BORDER_RADIUS, 0.0f));
}
if (props.hasKey(PROP_TINT_COLOR)) {
if (props.isNull(PROP_TINT_COLOR)) {
view.clearColorFilter();
} else {
final int tintColor = props.getInt(PROP_TINT_COLOR, Color.TRANSPARENT);
view.setColorFilter(tintColor);
}
@ReactProp(name = "borderRadius")
public void setBorderRadius(ReactImageView view, float borderRadius) {
view.setBorderRadius(borderRadius);
}
@ReactProp(name = ViewProps.RESIZE_MODE)
public void setResizeMode(ReactImageView view, @Nullable String resizeMode) {
view.setScaleType(ImageResizeMode.toScaleType(resizeMode));
}
@ReactProp(name = "tintColor", customType = "Color")
public void setTintColor(ReactImageView view, @Nullable Integer tintColor) {
if (tintColor == null) {
view.clearColorFilter();
} else {
view.setColorFilter(tintColor);
}
}
@Override
protected void onAfterUpdateTransaction(ReactImageView view) {
super.onAfterUpdateTransaction(view);
view.maybeUpdateView();
}
}

Просмотреть файл

@ -16,11 +16,10 @@ import android.widget.FrameLayout;
import android.widget.ProgressBar;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.uimanager.BaseViewPropertyApplicator;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewManager;
/**
* Manages instances of ProgressBar. ProgressBar is wrapped in a FrameLayout because the style of
@ -28,9 +27,10 @@ import com.facebook.react.uimanager.ViewManager;
* we have to drop the existing ProgressBar (if there is one) and create a new one with the style
* given.
*/
public class ReactProgressBarViewManager extends ViewManager<FrameLayout, ProgressBarShadowNode> {
public class ReactProgressBarViewManager extends
BaseViewManager<FrameLayout, ProgressBarShadowNode> {
@UIProp(UIProp.Type.STRING) public static final String PROP_STYLE = "styleAttr";
/* package */ static final String PROP_STYLE = "styleAttr";
/* package */ static final String REACT_CLASS = "AndroidProgressBar";
/* package */ static final String DEFAULT_STYLE = "Large";
@ -45,18 +45,15 @@ public class ReactProgressBarViewManager extends ViewManager<FrameLayout, Progre
return new FrameLayout(context);
}
@Override
public void updateView(FrameLayout view, CatalystStylesDiffMap props) {
BaseViewPropertyApplicator.applyCommonViewProperties(view, props);
if (props.hasKey(PROP_STYLE)) {
final int style = getStyleFromString(props.getString(PROP_STYLE));
view.removeAllViews();
view.addView(
new ProgressBar(view.getContext(), null, style),
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
@ReactProp(name = PROP_STYLE)
public void setStyle(FrameLayout view, @Nullable String styleName) {
final int style = getStyleFromString(styleName);
view.removeAllViews();
view.addView(
new ProgressBar(view.getContext(), null, style),
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
@Override

Просмотреть файл

@ -15,9 +15,8 @@ import java.util.Map;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.views.view.ReactClippingViewGroupHelper;
@ -33,11 +32,6 @@ public class ReactScrollViewManager
private static final String REACT_CLASS = "RCTScrollView";
@UIProp(UIProp.Type.BOOLEAN) public static final String PROP_SHOWS_VERTICAL_SCROLL_INDICATOR =
"showsVerticalScrollIndicator";
@UIProp(UIProp.Type.BOOLEAN) public static final String PROP_SHOWS_HORIZONTAL_SCROLL_INDICATOR =
"showsHorizontalScrollIndicator";
@Override
public String getName() {
return REACT_CLASS;
@ -48,20 +42,19 @@ public class ReactScrollViewManager
return new ReactScrollView(context);
}
@Override
public void updateView(ReactScrollView scrollView, CatalystStylesDiffMap props) {
super.updateView(scrollView, props);
if (props.hasKey(PROP_SHOWS_VERTICAL_SCROLL_INDICATOR)) {
scrollView.setVerticalScrollBarEnabled(
props.getBoolean(PROP_SHOWS_VERTICAL_SCROLL_INDICATOR, true));
}
@ReactProp(name = "showsVerticalScrollIndicator")
public void setShowsVerticalScrollIndicator(ReactScrollView view, boolean value) {
view.setVerticalScrollBarEnabled(value);
}
if (props.hasKey(PROP_SHOWS_HORIZONTAL_SCROLL_INDICATOR)) {
scrollView.setHorizontalScrollBarEnabled(
props.getBoolean(PROP_SHOWS_HORIZONTAL_SCROLL_INDICATOR, true));
}
@ReactProp(name = "showsHorizontalScrollIndicator")
public void setShowsHorizontalScrollIndicator(ReactScrollView view, boolean value) {
view.setHorizontalScrollBarEnabled(value);
}
ReactClippingViewGroupHelper.applyRemoveClippedSubviewsProperty(scrollView, props);
@ReactProp(name = ReactClippingViewGroupHelper.PROP_REMOVE_CLIPPED_SUBVIEWS)
public void setRemoveClippedSubviews(ReactScrollView view, boolean removeClippedSubviews) {
view.setRemoveClippedSubviews(removeClippedSubviews);
}
@Override

Просмотреть файл

@ -18,13 +18,11 @@ import android.widget.CompoundButton;
import com.facebook.csslayout.CSSNode;
import com.facebook.csslayout.MeasureOutput;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ReactShadowNode;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewProps;
/**
@ -33,8 +31,6 @@ import com.facebook.react.uimanager.ViewProps;
public class ReactSwitchManager extends SimpleViewManager<ReactSwitch> {
private static final String REACT_CLASS = "AndroidSwitch";
@UIProp(UIProp.Type.BOOLEAN) public static final String PROP_ENABLED = ViewProps.ENABLED;
@UIProp(UIProp.Type.BOOLEAN) public static final String PROP_ON = ViewProps.ON;
private static class ReactSwitchShadowNode extends ReactShadowNode implements
CSSNode.MeasureFunction {
@ -97,19 +93,18 @@ public class ReactSwitchManager extends SimpleViewManager<ReactSwitch> {
return view;
}
@Override
public void updateView(ReactSwitch view, CatalystStylesDiffMap props) {
super.updateView(view, props);
if (props.hasKey(PROP_ENABLED)) {
view.setEnabled(props.getBoolean(PROP_ENABLED, true));
}
if (props.hasKey(PROP_ON)) {
// we set the checked change listener to null and then restore it so that we don't fire an
// onChange event to JS when JS itself is updating the value of the switch
view.setOnCheckedChangeListener(null);
view.setOn(props.getBoolean(PROP_ON, false));
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
}
@ReactProp(name = ViewProps.ENABLED, defaultBoolean = true)
public void setEnabled(ReactSwitch view, boolean enabled) {
view.setEnabled(enabled);
}
@ReactProp(name = ViewProps.ON)
public void setOn(ReactSwitch view, boolean on) {
// we set the checked change listener to null and then restore it so that we don't fire an
// onChange event to JS when JS itself is updating the value of the switch
view.setOnCheckedChangeListener(null);
view.setOn(on);
view.setOnCheckedChangeListener(ON_CHECKED_CHANGE_LISTENER);
}
@Override

Просмотреть файл

@ -9,6 +9,8 @@
package com.facebook.react.views.text;
import javax.annotation.Nullable;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
@ -16,13 +18,13 @@ import android.view.Gravity;
import android.widget.TextView;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.uimanager.BaseViewPropertyApplicator;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewDefaults;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.common.annotations.VisibleForTesting;
@ -34,18 +36,11 @@ import com.facebook.react.common.annotations.VisibleForTesting;
* @{link ReactTextShadowNode} hierarchy to calculate a {@link Spannable} text representing the
* whole text subtree.
*/
public class ReactTextViewManager extends ViewManager<ReactTextView, ReactTextShadowNode> {
public class ReactTextViewManager extends BaseViewManager<ReactTextView, ReactTextShadowNode> {
@VisibleForTesting
public static final String REACT_CLASS = "RCTText";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_NUMBER_OF_LINES = ViewProps.NUMBER_OF_LINES;
@UIProp(UIProp.Type.STRING)
public static final String PROP_TEXT_ALIGN = ViewProps.TEXT_ALIGN;
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_LINE_HEIGHT = ViewProps.LINE_HEIGHT;
@Override
public String getName() {
return REACT_CLASS;
@ -56,38 +51,34 @@ public class ReactTextViewManager extends ViewManager<ReactTextView, ReactTextSh
return new ReactTextView(context);
}
@Override
public void updateView(ReactTextView view, CatalystStylesDiffMap props) {
BaseViewPropertyApplicator.applyCommonViewProperties(view, props);
// maxLines can only be set in master view (block), doesn't really make sense to set in a span
if (props.hasKey(PROP_NUMBER_OF_LINES)) {
view.setMaxLines(props.getInt(PROP_NUMBER_OF_LINES, ViewDefaults.NUMBER_OF_LINES));
view.setEllipsize(TextUtils.TruncateAt.END);
// maxLines can only be set in master view (block), doesn't really make sense to set in a span
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = ViewDefaults.NUMBER_OF_LINES)
public void setNumberOfLines(ReactTextView view, int numberOfLines) {
view.setMaxLines(numberOfLines);
view.setEllipsize(TextUtils.TruncateAt.END);
}
@ReactProp(name = ViewProps.TEXT_ALIGN)
public void setTextAlign(ReactTextView view, @Nullable String textAlign) {
if (textAlign == null || "auto".equals(textAlign)) {
view.setGravity(Gravity.NO_GRAVITY);
} else if ("left".equals(textAlign)) {
view.setGravity(Gravity.LEFT);
} else if ("right".equals(textAlign)) {
view.setGravity(Gravity.RIGHT);
} else if ("center".equals(textAlign)) {
view.setGravity(Gravity.CENTER_HORIZONTAL);
} else {
throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlign);
}
// same with textAlign
if (props.hasKey(PROP_TEXT_ALIGN)) {
final String textAlign = props.getString(PROP_TEXT_ALIGN);
if (textAlign == null || "auto".equals(textAlign)) {
view.setGravity(Gravity.NO_GRAVITY);
} else if ("left".equals(textAlign)) {
view.setGravity(Gravity.LEFT);
} else if ("right".equals(textAlign)) {
view.setGravity(Gravity.RIGHT);
} else if ("center".equals(textAlign)) {
view.setGravity(Gravity.CENTER_HORIZONTAL);
} else {
throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlign);
}
}
// same for lineSpacing
if (props.hasKey(PROP_LINE_HEIGHT)) {
if (props.isNull(PROP_LINE_HEIGHT)) {
view.setLineSpacing(0, 1);
} else {
float lineHeight =
PixelUtil.toPixelFromSP(props.getInt(PROP_LINE_HEIGHT, ViewDefaults.LINE_HEIGHT));
view.setLineSpacing(lineHeight, 0);
}
}
@ReactProp(name = ViewProps.LINE_HEIGHT, defaultFloat = Float.NaN)
public void setLineHeight(ReactTextView view, float lineHeight) {
if (Float.isNaN(lineHeight)) { // NaN will be used if property gets reset
view.setLineSpacing(0, 1);
} else {
view.setLineSpacing(PixelUtil.toPixelFromSP(lineHeight), 0);
}
}

Просмотреть файл

@ -54,6 +54,7 @@ public class ReactEditText extends EditText {
private int mNativeEventCount;
private @Nullable ArrayList<TextWatcher> mListeners;
private @Nullable TextWatcherDelegator mTextWatcherDelegator;
private int mStagedInputType;
public ReactEditText(Context context) {
super(context);
@ -69,6 +70,7 @@ public class ReactEditText extends EditText {
mIsJSSettingFocus = false;
mListeners = null;
mTextWatcherDelegator = null;
mStagedInputType = getInputType();
}
// After the text changes inside an EditText, TextView checks if a layout() has been requested.
@ -134,6 +136,26 @@ public class ReactEditText extends EditText {
}
}
/*protected*/ int getStagedInputType() {
return mStagedInputType;
}
/*package*/ void setStagedInputType(int stagedInputType) {
mStagedInputType = stagedInputType;
}
/*package*/ void commitStagedInputType() {
if (getInputType() != mStagedInputType) {
setInputType(mStagedInputType);
}
}
@Override
public void setInputType(int type) {
super.setInputType(type);
mStagedInputType = type;
}
/* package */ void requestFocusFromJS() {
mIsJSSettingFocus = true;
requestFocus();

Просмотреть файл

@ -13,7 +13,6 @@ import javax.annotation.Nullable;
import java.util.Map;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.SystemClock;
import android.text.Editable;
@ -31,14 +30,13 @@ import com.facebook.react.bridge.JSApplicationCausedNativeException;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.BaseViewPropertyApplicator;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewDefaults;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.text.DefaultStyleValuesUtil;
@ -46,7 +44,8 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil;
/**
* Manages instances of TextInput.
*/
public class ReactTextInputManager extends ViewManager<ReactEditText, ReactTextInputShadowNode> {
public class ReactTextInputManager extends
BaseViewManager<ReactEditText, ReactTextInputShadowNode> {
/* package */ static final String REACT_CLASS = "AndroidTextInput";
@ -57,34 +56,6 @@ public class ReactTextInputManager extends ViewManager<ReactEditText, ReactTextI
public static final String PROP_TEXT_INPUT_TEXT = "text";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_TEXT_INPUT_MOST_RECENT_EVENT_COUNT = "mostRecentEventCount";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_FONT_SIZE = ViewProps.FONT_SIZE;
@UIProp(UIProp.Type.BOOLEAN)
public static final String PROP_TEXT_INPUT_AUTO_CORRECT = "autoCorrect";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_TEXT_INPUT_AUTO_CAPITALIZE = "autoCapitalize";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_TEXT_ALIGN = "textAlign";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_TEXT_ALIGN_VERTICAL = "textAlignVertical";
@UIProp(UIProp.Type.STRING)
public static final String PROP_TEXT_INPUT_HINT = "placeholder";
@UIProp(UIProp.Type.COLOR)
public static final String PROP_TEXT_INPUT_HINT_COLOR = "placeholderTextColor";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_TEXT_INPUT_NUMLINES = ViewProps.NUMBER_OF_LINES;
@UIProp(UIProp.Type.BOOLEAN)
public static final String PROP_TEXT_INPUT_MULTILINE = "multiline";
@UIProp(UIProp.Type.STRING)
public static final String PROP_TEXT_INPUT_KEYBOARD_TYPE = "keyboardType";
@UIProp(UIProp.Type.BOOLEAN)
public static final String PROP_TEXT_INPUT_PASSWORD = "password";
@UIProp(UIProp.Type.BOOLEAN)
public static final String PROP_TEXT_INPUT_EDITABLE = "editable";
@UIProp(UIProp.Type.COLOR)
public static final String PROP_TEXT_INPUT_UNDERLINE_COLOR = "underlineColorAndroid";
@UIProp(UIProp.Type.NUMBER)
public static final String PROP_TEST_ID = "testID";
private static final String KEYBOARD_TYPE_EMAIL_ADDRESS = "email-address";
private static final String KEYBOARD_TYPE_NUMERIC = "numeric";
@ -179,140 +150,140 @@ public class ReactTextInputManager extends ViewManager<ReactEditText, ReactTextI
}
}
@ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = ViewDefaults.FONT_SIZE_SP)
public void setFontSize(ReactEditText view, float fontSize) {
view.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
(int) Math.ceil(PixelUtil.toPixelFromSP(fontSize)));
}
// Prevents flickering color while waiting for JS update.
@ReactProp(name = ViewProps.COLOR, customType = "Color")
public void setColor(ReactEditText view, @Nullable Integer color) {
if (color == null) {
view.setTextColor(DefaultStyleValuesUtil.getDefaultTextColor(view.getContext()));
} else {
view.setTextColor(color);
}
}
@ReactProp(name = "placeholder")
public void setPlaceholder(ReactEditText view, @Nullable String placeholder) {
view.setHint(placeholder);
}
@ReactProp(name = "placeholderTextColor", customType = "Color")
public void setPlaceholderTextColor(ReactEditText view, @Nullable Integer color) {
if (color == null) {
view.setHintTextColor(DefaultStyleValuesUtil.getDefaultTextColorHint(view.getContext()));
} else {
view.setHintTextColor(color);
}
}
@ReactProp(name = "underlineColorAndroid", customType = "Color")
public void setUnderlineColor(ReactEditText view, @Nullable Integer underlineColor) {
if (underlineColor == null) {
view.getBackground().clearColorFilter();
} else {
view.getBackground().setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
}
}
@ReactProp(name = "textAlign")
public void setTextAlign(ReactEditText view, int gravity) {
view.setGravityHorizontal(gravity);
}
@ReactProp(name = "textAlignVertical")
public void setTextAlignVertical(ReactEditText view, int gravity) {
view.setGravityVertical(gravity);
}
@ReactProp(name = "editable", defaultBoolean = true)
public void setEditable(ReactEditText view, boolean editable) {
view.setEnabled(editable);
}
@ReactProp(name = ViewProps.NUMBER_OF_LINES, defaultInt = 1)
public void setNumLines(ReactEditText view, int numLines) {
view.setLines(numLines);
}
@ReactProp(name = "autoCorrect")
public void setAutoCorrect(ReactEditText view, @Nullable Boolean autoCorrect) {
// clear auto correct flags, set SUGGESTIONS or NO_SUGGESTIONS depending on value
updateStagedInputTypeFlag(
view,
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS,
autoCorrect != null ?
(autoCorrect.booleanValue() ?
InputType.TYPE_TEXT_FLAG_AUTO_CORRECT : InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS)
: 0);
}
@ReactProp(name = "multiline", defaultBoolean = false)
public void setMultiline(ReactEditText view, boolean multiline) {
updateStagedInputTypeFlag(
view,
multiline ? 0 : InputType.TYPE_TEXT_FLAG_MULTI_LINE,
multiline ? InputType.TYPE_TEXT_FLAG_MULTI_LINE : 0);
}
@ReactProp(name = "password", defaultBoolean = false)
public void setPassword(ReactEditText view, boolean password) {
updateStagedInputTypeFlag(
view,
password ? 0 : InputType.TYPE_TEXT_VARIATION_PASSWORD,
password ? InputType.TYPE_TEXT_VARIATION_PASSWORD : 0);
}
@ReactProp(name = "autoCapitalize", defaultInt = InputType.TYPE_CLASS_TEXT)
public void setAutoCapitalize(ReactEditText view, int autoCapitalize) {
int flagsToSet = 0;
switch (autoCapitalize) {
case InputType.TYPE_TEXT_FLAG_CAP_SENTENCES:
case InputType.TYPE_TEXT_FLAG_CAP_WORDS:
case InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS:
case InputType.TYPE_CLASS_TEXT:
flagsToSet = autoCapitalize;
break;
default:
throw new
JSApplicationCausedNativeException("Invalid autoCapitalize value: " + autoCapitalize);
}
updateStagedInputTypeFlag(
view,
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_CAP_WORDS |
InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS,
flagsToSet);
}
@ReactProp(name = "keyboardType")
public void setKeyboardType(ReactEditText view, @Nullable String keyboardType) {
int flagsToSet = 0;
if (KEYBOARD_TYPE_NUMERIC.equalsIgnoreCase(keyboardType)) {
flagsToSet = InputType.TYPE_CLASS_NUMBER;
} else if (KEYBOARD_TYPE_EMAIL_ADDRESS.equalsIgnoreCase(keyboardType)) {
flagsToSet = InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
}
updateStagedInputTypeFlag(
view,
InputType.TYPE_CLASS_NUMBER | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS,
flagsToSet);
}
@Override
public void updateView(ReactEditText view, CatalystStylesDiffMap props) {
BaseViewPropertyApplicator.applyCommonViewProperties(view, props);
protected void onAfterUpdateTransaction(ReactEditText view) {
super.onAfterUpdateTransaction(view);
view.commitStagedInputType();
}
if (props.hasKey(PROP_FONT_SIZE)) {
float textSize = props.getFloat(PROP_FONT_SIZE, ViewDefaults.FONT_SIZE_SP);
view.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
(int) Math.ceil(PixelUtil.toPixelFromSP(textSize)));
}
//Prevents flickering color while waiting for JS update.
if (props.hasKey(ViewProps.COLOR)) {
if (props.isNull(ViewProps.COLOR)) {
view.setTextColor(DefaultStyleValuesUtil.getDefaultTextColor(view.getContext()));
} else {
final int textColor = props.getInt(ViewProps.COLOR, Color.TRANSPARENT);
view.setTextColor(textColor);
}
}
if (props.hasKey(PROP_TEXT_INPUT_HINT)) {
view.setHint(props.getString(PROP_TEXT_INPUT_HINT));
}
if (props.hasKey(PROP_TEXT_INPUT_HINT_COLOR)) {
if (props.isNull(PROP_TEXT_INPUT_HINT_COLOR)) {
view.setHintTextColor(DefaultStyleValuesUtil.getDefaultTextColorHint(view.getContext()));
} else {
final int hintColor = props.getInt(PROP_TEXT_INPUT_HINT_COLOR, Color.TRANSPARENT);
view.setHintTextColor(hintColor);
}
}
if (props.hasKey(PROP_TEXT_INPUT_UNDERLINE_COLOR)) {
if (props.isNull(PROP_TEXT_INPUT_UNDERLINE_COLOR)) {
view.getBackground().clearColorFilter();
} else {
final int underlineColor =
props.getInt(PROP_TEXT_INPUT_UNDERLINE_COLOR, Color.TRANSPARENT);
view.getBackground().setColorFilter(underlineColor, PorterDuff.Mode.SRC_IN);
}
}
if (props.hasKey(PROP_TEXT_ALIGN)) {
int gravityHorizontal = props.getInt(PROP_TEXT_ALIGN, 0);
view.setGravityHorizontal(gravityHorizontal);
}
if (props.hasKey(PROP_TEXT_ALIGN_VERTICAL)) {
int gravityVertical = props.getInt(PROP_TEXT_ALIGN_VERTICAL, 0);
view.setGravityVertical(gravityVertical);
}
if (props.hasKey(PROP_TEXT_INPUT_EDITABLE)) {
if (props.getBoolean(PROP_TEXT_INPUT_EDITABLE, true)) {
view.setEnabled(true);
} else {
view.setEnabled(false);
}
}
// newInputType will collect all content attributes that have to be set in the InputText.
int newInputType = view.getInputType();
if (props.hasKey(PROP_TEXT_INPUT_AUTO_CORRECT)) {
// clear auto correct flags
newInputType
&= ~(InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
if (props.getBoolean(PROP_TEXT_INPUT_AUTO_CORRECT, false)) {
newInputType |= InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
} else if (!props.isNull(PROP_TEXT_INPUT_AUTO_CORRECT)) {
newInputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
}
}
if (props.hasKey(PROP_TEXT_INPUT_MULTILINE)) {
if (props.getBoolean(PROP_TEXT_INPUT_MULTILINE, false)) {
newInputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
} else {
newInputType &= ~InputType.TYPE_TEXT_FLAG_MULTI_LINE;
}
}
if (props.hasKey(PROP_TEXT_INPUT_KEYBOARD_TYPE)) {
// reset keyboard type defaults
newInputType = newInputType &
~InputType.TYPE_CLASS_NUMBER &
~InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
String keyboardType = props.getString(PROP_TEXT_INPUT_KEYBOARD_TYPE);
if (KEYBOARD_TYPE_NUMERIC.equalsIgnoreCase(keyboardType)) {
newInputType |= InputType.TYPE_CLASS_NUMBER;
} else if (KEYBOARD_TYPE_EMAIL_ADDRESS.equalsIgnoreCase(keyboardType)) {
newInputType |= InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
}
}
if (props.hasKey(PROP_TEXT_INPUT_PASSWORD)) {
if (props.getBoolean(PROP_TEXT_INPUT_PASSWORD, false)) {
newInputType |= InputType.TYPE_TEXT_VARIATION_PASSWORD;
} else {
newInputType &= ~InputType.TYPE_TEXT_VARIATION_PASSWORD;
}
}
if (props.hasKey(PROP_TEXT_INPUT_AUTO_CAPITALIZE)) {
// clear auto capitalization flags
newInputType &= ~(
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES |
InputType.TYPE_TEXT_FLAG_CAP_WORDS |
InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
int autoCapitalize = props.getInt(PROP_TEXT_INPUT_AUTO_CAPITALIZE, InputType.TYPE_CLASS_TEXT);
switch (autoCapitalize) {
case InputType.TYPE_TEXT_FLAG_CAP_SENTENCES:
case InputType.TYPE_TEXT_FLAG_CAP_WORDS:
case InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS:
case InputType.TYPE_CLASS_TEXT:
newInputType |= autoCapitalize;
break;
default:
throw new
JSApplicationCausedNativeException("Invalid autoCapitalize value: " + autoCapitalize);
}
}
if (view.getInputType() != newInputType) {
view.setInputType(newInputType);
}
if (props.hasKey(PROP_TEXT_INPUT_NUMLINES)) {
view.setLines(props.getInt(PROP_TEXT_INPUT_NUMLINES, 1));
}
private static void updateStagedInputTypeFlag(
ReactEditText view,
int flagsToUnset,
int flagsToSet) {
view.setStagedInputType((view.getStagedInputType() & ~flagsToUnset) | flagsToSet);
}
private class ReactTextInputTextWatcher implements TextWatcher {

Просмотреть файл

@ -109,8 +109,8 @@ import com.facebook.react.views.text.ReactTextShadowNode;
styles.getInt(ReactTextInputManager.PROP_TEXT_INPUT_MOST_RECENT_EVENT_COUNT, 0);
}
if (styles.hasKey(ReactTextInputManager.PROP_TEXT_INPUT_NUMLINES)) {
mNumLines = styles.getInt(ReactTextInputManager.PROP_TEXT_INPUT_NUMLINES, UNSET);
if (styles.hasKey(ViewProps.NUMBER_OF_LINES)) {
mNumLines = styles.getInt(ViewProps.NUMBER_OF_LINES, UNSET);
}
}

Просмотреть файл

@ -24,10 +24,9 @@ import android.view.View;
import com.facebook.react.R;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.CatalystStylesDiffMap;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.UIProp;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.toolbar.events.ToolbarClickEvent;
@ -39,21 +38,6 @@ public class ReactToolbarManager extends ViewGroupManager<Toolbar> {
private static final String REACT_CLASS = "ToolbarAndroid";
@UIProp(UIProp.Type.STRING)
public static final String PROP_LOGO = "logo";
@UIProp(UIProp.Type.STRING)
public static final String PROP_NAV_ICON = "navIcon";
@UIProp(UIProp.Type.STRING)
public static final String PROP_SUBTITLE = "subtitle";
@UIProp(UIProp.Type.COLOR)
public static final String PROP_SUBTITLE_COLOR = "subtitleColor";
@UIProp(UIProp.Type.STRING)
public static final String PROP_TITLE = "title";
@UIProp(UIProp.Type.COLOR)
public static final String PROP_TITLE_COLOR = "titleColor";
@UIProp(UIProp.Type.ARRAY)
public static final String PROP_ACTIONS = "actions";
private static final String PROP_ACTION_ICON = "icon";
private static final String PROP_ACTION_SHOW = "show";
private static final String PROP_ACTION_SHOW_WITH_TEXT = "showWithText";
@ -69,44 +53,82 @@ public class ReactToolbarManager extends ViewGroupManager<Toolbar> {
return new Toolbar(reactContext);
}
@Override
public void updateView(Toolbar toolbar, CatalystStylesDiffMap props) {
super.updateView(toolbar, props);
@ReactProp(name = "logo")
public void setLogo(Toolbar view, @Nullable String logo) {
if (logo != null) {
view.setLogo(getDrawableResourceByName(view.getContext(), logo));
} else {
view.setLogo(null);
}
}
int[] defaultColors = getDefaultColors(toolbar.getContext());
if (props.hasKey(PROP_SUBTITLE)) {
toolbar.setSubtitle(props.getString(PROP_SUBTITLE));
@ReactProp(name = "navIcon")
public void setNavIcon(Toolbar view, @Nullable String navIcon) {
if (navIcon != null) {
view.setNavigationIcon(getDrawableResourceByName(view.getContext(), navIcon));
} else {
view.setNavigationIcon(null);
}
if (props.hasKey(PROP_SUBTITLE_COLOR)) {
final int subtitleColor = props.getInt(PROP_SUBTITLE_COLOR, defaultColors[1]);
toolbar.setSubtitleTextColor(subtitleColor);
}
@ReactProp(name = "subtitle")
public void setSubtitle(Toolbar view, @Nullable String subtitle) {
view.setSubtitle(subtitle);
}
@ReactProp(name = "subtitleColor", customType = "Color")
public void setSubtitleColor(Toolbar view, @Nullable Integer subtitleColor) {
int[] defaultColors = getDefaultColors(view.getContext());
if (subtitleColor != null) {
view.setSubtitleTextColor(subtitleColor);
} else {
view.setSubtitleTextColor(defaultColors[1]);
}
if (props.hasKey(PROP_TITLE)) {
toolbar.setTitle(props.getString(PROP_TITLE));
}
@ReactProp(name = "title")
public void setTitle(Toolbar view, @Nullable String title) {
view.setTitle(title);
}
@ReactProp(name = "titleColor", customType = "Color")
public void setTitleColor(Toolbar view, @Nullable Integer titleColor) {
int[] defaultColors = getDefaultColors(view.getContext());
if (titleColor != null) {
view.setTitleTextColor(titleColor);
} else {
view.setTitleTextColor(defaultColors[0]);
}
if (props.hasKey(PROP_TITLE_COLOR)) {
final int titleColor = props.getInt(PROP_TITLE_COLOR, defaultColors[0]);
toolbar.setTitleTextColor(titleColor);
}
if (props.hasKey(PROP_NAV_ICON)) {
String navIcon = props.getString(PROP_NAV_ICON);
if (navIcon != null) {
toolbar.setNavigationIcon(getDrawableResourceByName(toolbar.getContext(), navIcon));
} else {
toolbar.setNavigationIcon(null);
}
@ReactProp(name = "actions")
public void setActions(Toolbar view, @Nullable ReadableArray actions) {
Menu menu = view.getMenu();
menu.clear();
if (actions != null) {
for (int i = 0; i < actions.size(); i++) {
ReadableMap action = actions.getMap(i);
MenuItem item = menu.add(Menu.NONE, Menu.NONE, i, action.getString(PROP_ACTION_TITLE));
String icon = action.hasKey(PROP_ACTION_ICON) ? action.getString(PROP_ACTION_ICON) : null;
if (icon != null) {
item.setIcon(getDrawableResourceByName(view.getContext(), icon));
}
String show = action.hasKey(PROP_ACTION_SHOW) ? action.getString(PROP_ACTION_SHOW) : null;
if (show != null) {
int showAsAction = MenuItem.SHOW_AS_ACTION_NEVER;
if ("always".equals(show)) {
showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
} else if ("ifRoom".equals(show)) {
showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM;
}
if (action.hasKey(PROP_ACTION_SHOW_WITH_TEXT) &&
action.getBoolean(PROP_ACTION_SHOW_WITH_TEXT)) {
showAsAction = showAsAction | MenuItem.SHOW_AS_ACTION_WITH_TEXT;
}
item.setShowAsAction(showAsAction);
}
}
}
if (props.hasKey(PROP_LOGO)) {
String logo = props.getString(PROP_LOGO);
if (logo != null) {
toolbar.setLogo(getDrawableResourceByName(toolbar.getContext(), logo));
} else {
toolbar.setLogo(null);
}
}
if (props.hasKey(PROP_ACTIONS)) {
setActions(toolbar, props.getArray(PROP_ACTIONS));
}
}
@Override
@ -141,35 +163,6 @@ public class ReactToolbarManager extends ViewGroupManager<Toolbar> {
return true;
}
private static void setActions(Toolbar toolbar, @Nullable ReadableArray actions) {
Menu menu = toolbar.getMenu();
menu.clear();
if (actions != null) {
for (int i = 0; i < actions.size(); i++) {
ReadableMap action = actions.getMap(i);
MenuItem item = menu.add(Menu.NONE, Menu.NONE, i, action.getString(PROP_ACTION_TITLE));
String icon = action.hasKey(PROP_ACTION_ICON) ? action.getString(PROP_ACTION_ICON) : null;
if (icon != null) {
item.setIcon(getDrawableResourceByName(toolbar.getContext(), icon));
}
String show = action.hasKey(PROP_ACTION_SHOW) ? action.getString(PROP_ACTION_SHOW) : null;
if (show != null) {
int showAsAction = MenuItem.SHOW_AS_ACTION_NEVER;
if ("always".equals(show)) {
showAsAction = MenuItem.SHOW_AS_ACTION_ALWAYS;
} else if ("ifRoom".equals(show)) {
showAsAction = MenuItem.SHOW_AS_ACTION_IF_ROOM;
}
if (action.hasKey(PROP_ACTION_SHOW_WITH_TEXT) &&
action.getBoolean(PROP_ACTION_SHOW_WITH_TEXT)) {
showAsAction = showAsAction | MenuItem.SHOW_AS_ACTION_WITH_TEXT;
}
item.setShowAsAction(showAsAction);
}
}
}
}
private static int[] getDefaultColors(Context context) {
Resources.Theme theme = context.getTheme();
TypedArray toolbarStyle = null;

Просмотреть файл

@ -56,19 +56,4 @@ public class ReactClippingViewGroupHelper {
}
view.getDrawingRect(outputRect);
}
/**
* Can be used by view's manager in {@link ViewManager#updateView} method to update property
* {@code removeClippedSubviews} in the view.
*
* @param view view instance passed to {@link ViewManager#updateView}
* @param props property map passed to {@link ViewManager#updateView}
*/
public static void applyRemoveClippedSubviewsProperty(
ReactClippingViewGroup view,
CatalystStylesDiffMap props) {
if (props.hasKey(PROP_REMOVE_CLIPPED_SUBVIEWS)) {
view.setRemoveClippedSubviews(props.getBoolean(PROP_REMOVE_CLIPPED_SUBVIEWS, false));
}
}
}