Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set rounded rectangle mask on TouchableNativeFeedback's ripples #25342

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -9,8 +9,6 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Build;
Expand All @@ -30,7 +28,9 @@ public class ReactDrawableHelper {

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static Drawable createDrawableFromJSDescription(
Context context, ReadableMap drawableDescriptionDict) {
ReactViewGroup view,
ReadableMap drawableDescriptionDict) {
Context context = view.getContext();
String type = drawableDescriptionDict.getString("type");
if ("ThemeAttrAndroid".equals(type)) {
String attr = drawableDescriptionDict.getString("attribute");
Expand Down Expand Up @@ -75,7 +75,7 @@ public static Drawable createDrawableFromJSDescription(
if (!drawableDescriptionDict.hasKey("borderless")
|| drawableDescriptionDict.isNull("borderless")
|| !drawableDescriptionDict.getBoolean("borderless")) {
mask = new ColorDrawable(Color.WHITE);
mask = view.getBorderRadiusMask();
}
ColorStateList colorStateList =
new ColorStateList(new int[][] {new int[] {}}, new int[] {color});
Expand Down
Expand Up @@ -18,6 +18,8 @@
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
Expand Down Expand Up @@ -282,10 +284,46 @@ public void setBorderRadius(float borderRadius, int position) {
}
}

public float[] getBorderRadius() {
final float borderRadius = mReactBackgroundDrawable.getFullBorderRadius();
float topLeftBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_LEFT);
float topRightBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.TOP_RIGHT);
float bottomLeftBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_LEFT);
float bottomRightBorderRadius =
mReactBackgroundDrawable.getBorderRadiusOrDefaultTo(
borderRadius, ReactViewBackgroundDrawable.BorderRadiusLocation.BOTTOM_RIGHT);

return new float[] {
topLeftBorderRadius,
topLeftBorderRadius,
topRightBorderRadius,
topRightBorderRadius,
bottomRightBorderRadius,
bottomRightBorderRadius,
bottomLeftBorderRadius,
bottomLeftBorderRadius
};
}

public void setBorderStyle(@Nullable String style) {
getOrCreateReactViewBackground().setBorderStyle(style);
}

public Drawable getBorderRadiusMask() {
RoundRectShape r = new RoundRectShape(getBorderRadius(), null, null);

ShapeDrawable shapeDrawable = new ShapeDrawable(r);
shapeDrawable.getPaint().setColor(Color.WHITE);

return shapeDrawable;
}

@Override
public void setRemoveClippedSubviews(boolean removeClippedSubviews) {
if (removeClippedSubviews == mRemoveClippedSubviews) {
Expand Down
Expand Up @@ -52,6 +52,9 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
private static final int CMD_SET_PRESSED = 2;
private static final String HOTSPOT_UPDATE_KEY = "hotspotUpdate";

private ReadableMap mBg = null;
private ReadableMap mFg = null;

@ReactProp(name = "accessible")
public void setAccessible(ReactViewGroup view, boolean accessible) {
view.setFocusable(accessible);
Expand Down Expand Up @@ -118,6 +121,14 @@ public void setBorderRadius(ReactViewGroup view, int index, float borderRadius)
} else {
view.setBorderRadius(borderRadius, index - 1);
}

if (mBg != null) {
setNativeBackground(view, mBg);
}

if (mFg != null) {
setNativeForeground(view, mFg);
}
}

@ReactProp(name = "borderStyle")
Expand Down Expand Up @@ -158,19 +169,21 @@ public void setPointerEvents(ReactViewGroup view, @Nullable String pointerEvents

@ReactProp(name = "nativeBackgroundAndroid")
public void setNativeBackground(ReactViewGroup view, @Nullable ReadableMap bg) {
mBg = bg;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way to track the current background style object passed into the React Component? I need to keep track of the last background style to reapply the ripple drawable with new border radius styles.

I wasn't sure if assigning this to a variable was the best approach, but I couldn't find another way to do it.

view.setTranslucentBackgroundDrawable(
bg == null
? null
: ReactDrawableHelper.createDrawableFromJSDescription(view.getContext(), bg));
: ReactDrawableHelper.createDrawableFromJSDescription(view, bg));
}

@TargetApi(Build.VERSION_CODES.M)
@ReactProp(name = "nativeForegroundAndroid")
public void setNativeForeground(ReactViewGroup view, @Nullable ReadableMap fg) {
mFg = fg;
view.setForeground(
fg == null
? null
: ReactDrawableHelper.createDrawableFromJSDescription(view.getContext(), fg));
: ReactDrawableHelper.createDrawableFromJSDescription(view, fg));
}

@ReactProp(
Expand Down