From 656126a2f1c8a1170faab61e1eeda8545b3ce944 Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Fri, 25 Sep 2015 14:43:28 -0700 Subject: [PATCH] Convert remaining viewmanager to @ReactProp. Differential Revision: D2481816 committer: Service User --- .../react/views/drawer/ReactDrawerLayout.java | 4 +- .../drawer/ReactDrawerLayoutManager.java | 35 +- .../react/views/image/ReactImageManager.java | 57 ++-- .../ReactProgressBarViewManager.java | 31 +- .../views/scroll/ReactScrollViewManager.java | 31 +- .../views/switchview/ReactSwitchManager.java | 31 +- .../views/text/ReactTextViewManager.java | 73 ++--- .../react/views/textinput/ReactEditText.java | 22 ++ .../textinput/ReactTextInputManager.java | 301 ++++++++---------- .../textinput/ReactTextInputShadowNode.java | 4 +- .../views/toolbar/ReactToolbarManager.java | 149 +++++---- .../view/ReactClippingViewGroupHelper.java | 15 - 12 files changed, 345 insertions(+), 408 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java index 9d0d32405..abdb4a04d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayout.java @@ -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(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java index eb07905a7..75ab360c3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java @@ -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 { @@ -30,15 +29,6 @@ public class ReactImageManager extends SimpleViewManager { 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 { 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(); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.java index 296e9d400..acc3eb1e5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/ReactProgressBarViewManager.java @@ -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 { +public class ReactProgressBarViewManager extends + BaseViewManager { - @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 { 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 { 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 diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java index e78b15cef..43ea797d8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java @@ -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 { +public class ReactTextViewManager extends BaseViewManager { @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 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(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 1ec44e25d..8a4833225 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -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 { +public class ReactTextInputManager extends + BaseViewManager { /* package */ static final String REACT_CLASS = "AndroidTextInput"; @@ -57,34 +56,6 @@ public class ReactTextInputManager extends ViewManager { 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 { 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 { 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; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewGroupHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewGroupHelper.java index 67a2e9d45..1345bdd89 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewGroupHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewGroupHelper.java @@ -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)); - } - } }