Implement @ReactProp nativeBackgroundAndroid in RCTView

Summary: RCTView has a property called nativeBackgroundAndroid that shows a ripple effect (or any other Drawable) when pressed and holded. This diff is adding support for the property.

Reviewed By: ahmedre

Differential Revision: D2768671
This commit is contained in:
Denis Koroskin 2015-12-17 15:02:54 -08:00 committed by Ahmed El-Helw
parent 381bf1b76f
commit c144bcbc96
3 changed files with 126 additions and 0 deletions

View File

@ -16,6 +16,7 @@ import javax.annotation.Nullable;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@ -56,6 +57,7 @@ import com.facebook.react.uimanager.ReactCompoundView;
private int mDrawChildIndex = 0;
private boolean mIsAttached = false;
private boolean mIsLayoutRequested = false;
private Drawable mHotspot;
/* package */ FlatViewGroup(Context context) {
super(context);
@ -101,6 +103,10 @@ import com.facebook.react.uimanager.ReactCompoundView;
"Did not draw all children: " + mDrawChildIndex + " / " + getChildCount());
}
mDrawChildIndex = 0;
if (mHotspot != null) {
mHotspot.draw(canvas);
}
}
@Override
@ -140,6 +146,56 @@ import com.facebook.react.uimanager.ReactCompoundView;
dispatchOnDetached(mAttachDetachListeners);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (mHotspot != null) {
mHotspot.setBounds(0, 0, w, h);
invalidate();
}
}
@Override
public void dispatchDrawableHotspotChanged(float x, float y) {
if (mHotspot != null) {
mHotspot.setHotspot(x, y);
invalidate();
}
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
if (mHotspot != null && mHotspot.isStateful()) {
mHotspot.setState(getDrawableState());
}
}
@Override
public void jumpDrawablesToCurrentState() {
super.jumpDrawablesToCurrentState();
if (mHotspot != null) {
mHotspot.jumpToCurrentState();
}
}
/* package */ void setHotspot(Drawable hotspot) {
if (mHotspot != null) {
mHotspot.setCallback(null);
unscheduleDrawable(mHotspot);
}
if (hotspot != null) {
hotspot.setCallback(this);
if (hotspot.isStateful()) {
hotspot.setState(getDrawableState());
}
}
mHotspot = hotspot;
invalidate();
}
/* package */ void drawNextChild(Canvas canvas) {
View child = getChildAt(mDrawChildIndex);
super.drawChild(canvas, child, getDrawingTime());

View File

@ -11,6 +11,7 @@ package com.facebook.react.flat;
import javax.annotation.Nullable;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ReactPropGroup;
@ -48,6 +49,13 @@ import com.facebook.react.uimanager.ViewProps;
getMutableBorder().setBorderWidth(type, PixelUtil.toPixelFromDIP(borderWidth));
}
@ReactProp(name = "nativeBackgroundAndroid")
public void setHotspot(@Nullable ReadableMap bg) {
if (bg != null) {
forceMountToView();
}
}
@ReactPropGroup(names = {
"borderColor", "borderLeftColor", "borderRightColor", "borderTopColor", "borderBottomColor"
}, customType = "Color", defaultDouble = Double.NaN)

View File

@ -9,16 +9,42 @@
package com.facebook.react.flat;
import javax.annotation.Nullable;
import java.util.Map;
import android.os.Build;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ReactPropGroup;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.views.view.ReactDrawableHelper;
/**
* ViewManager that creates instances of RCTView.
*/
/* package */ final class RCTViewManager extends FlatViewManager {
private static final int[] TMP_INT_ARRAY = new int[2];
private static final int CMD_HOTSPOT_UPDATE = 1;
private static final int CMD_SET_PRESSED = 2;
@Override
public String getName() {
return "RCTView";
}
public Map<String, Integer> getCommandsMap() {
return MapBuilder.of("hotspotUpdate", CMD_HOTSPOT_UPDATE, "setPressed", CMD_SET_PRESSED);
}
@Override
public RCTView createShadowNodeInstance() {
return new RCTView();
@ -28,4 +54,40 @@ package com.facebook.react.flat;
public Class<RCTView> getShadowNodeClass() {
return RCTView.class;
}
@ReactProp(name = "nativeBackgroundAndroid")
public void setHotspot(FlatViewGroup view, @Nullable ReadableMap bg) {
view.setHotspot(bg == null ?
null : ReactDrawableHelper.createDrawableFromJSDescription(view.getContext(), bg));
}
@Override
public void receiveCommand(
FlatViewGroup view,
int commandId,
@Nullable ReadableArray args) {
switch (commandId) {
case CMD_HOTSPOT_UPDATE: {
if (args == null || args.size() != 2) {
throw new JSApplicationIllegalArgumentException(
"Illegal number of arguments for 'updateHotspot' command");
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
view.getLocationOnScreen(TMP_INT_ARRAY);
float x = PixelUtil.toPixelFromDIP(args.getDouble(0)) - TMP_INT_ARRAY[0];
float y = PixelUtil.toPixelFromDIP(args.getDouble(1)) - TMP_INT_ARRAY[1];
view.drawableHotspotChanged(x, y);
}
break;
}
case CMD_SET_PRESSED: {
if (args == null || args.size() != 1) {
throw new JSApplicationIllegalArgumentException(
"Illegal number of arguments for 'setPressed' command");
}
view.setPressed(args.getBoolean(0));
break;
}
}
}
}