Skip to content

Commit e4fbb84

Browse files
pekingmeleticiarossi
authored andcommitted
[Shape] Fixed stroke path calculation for custom interpolation start shape.
PiperOrigin-RevId: 629942322
1 parent d44a06c commit e4fbb84

File tree

1 file changed

+57
-20
lines changed

1 file changed

+57
-20
lines changed

lib/java/com/google/android/material/shape/MaterialShapeDrawable.java

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public class MaterialShapeDrawable extends Drawable implements TintAwareDrawable
112112
public @interface CompatibilityShadowMode {}
113113

114114
private static final Paint clearPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
115+
115116
static {
116117
clearPaint.setColor(Color.WHITE);
117118
clearPaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
@@ -134,6 +135,7 @@ public class MaterialShapeDrawable extends Drawable implements TintAwareDrawable
134135
private final Region transparentRegion = new Region();
135136
private final Region scratchRegion = new Region();
136137
private ShapeAppearanceModel strokeShapeAppearance;
138+
private ShapeAppearanceModel strokeInterpolationStartShapeAppearance;
137139

138140
private final Paint fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
139141
private final Paint strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -226,9 +228,7 @@ public MaterialShapeDrawable(@NonNull ShapeAppearanceModel shapeAppearanceModel)
226228
this(new MaterialShapeDrawableState(shapeAppearanceModel, null));
227229
}
228230

229-
/**
230-
* @hide
231-
*/
231+
/** @hide */
232232
@RestrictTo(LIBRARY_GROUP)
233233
protected MaterialShapeDrawable(@NonNull MaterialShapeDrawableState drawableState) {
234234
this.drawableState = drawableState;
@@ -301,7 +301,7 @@ public ShapeAppearanceModel getShapeAppearanceModel() {
301301
* Set the shape appearance when interpolation is 0.
302302
*
303303
* @param startShape the ShapeAppearanceModel for the shape when interpolation is 0. The edge
304-
* treatments within it are ignored.
304+
* treatments within it are ignored.
305305
* @hide
306306
*/
307307
@RestrictTo(LIBRARY_GROUP)
@@ -492,9 +492,7 @@ public void setStrokeWidth(float strokeWidth) {
492492
invalidateSelf();
493493
}
494494

495-
/**
496-
* Get the tint color factoring in any other runtime modifications such as elevation overlays.
497-
*/
495+
/** Get the tint color factoring in any other runtime modifications such as elevation overlays. */
498496
@ColorInt
499497
public int getResolvedTintColor() {
500498
return resolvedTintColor;
@@ -1093,7 +1091,13 @@ private void maybeDrawCompatShadow(@NonNull Canvas canvas) {
10931091
@RestrictTo(LIBRARY_GROUP)
10941092
protected void drawShape(
10951093
@NonNull Canvas canvas, @NonNull Paint paint, @NonNull Path path, @NonNull RectF bounds) {
1096-
drawShape(canvas, paint, path, drawableState.shapeAppearanceModel, bounds);
1094+
drawShape(
1095+
canvas,
1096+
paint,
1097+
path,
1098+
drawableState.shapeAppearanceModel,
1099+
drawableState.interpolationStartShapeAppearanceModel,
1100+
bounds);
10971101
}
10981102

10991103
/** Draw the path or try to draw a round rect if possible. */
@@ -1102,11 +1106,12 @@ private void drawShape(
11021106
@NonNull Paint paint,
11031107
@NonNull Path path,
11041108
@NonNull ShapeAppearanceModel shapeAppearanceModel,
1109+
@NonNull ShapeAppearanceModel interpolationStartShapeAppearanceModel,
11051110
@NonNull RectF bounds) {
11061111
if (shapeAppearanceModel.isRoundRect(bounds)) {
11071112
float endRadius = shapeAppearanceModel.getTopLeftCornerSize().getCornerSize(bounds);
1108-
shapeAppearanceModel = drawableState.interpolationStartShapeAppearanceModel;
1109-
float startRadius = shapeAppearanceModel.getTopLeftCornerSize().getCornerSize(bounds);
1113+
float startRadius =
1114+
interpolationStartShapeAppearanceModel.getTopLeftCornerSize().getCornerSize(bounds);
11101115
float radius = lerp(startRadius, endRadius, drawableState.interpolation);
11111116
canvas.drawRoundRect(bounds, radius, radius, paint);
11121117
} else {
@@ -1115,7 +1120,13 @@ private void drawShape(
11151120
}
11161121

11171122
private void drawFillShape(@NonNull Canvas canvas) {
1118-
drawShape(canvas, fillPaint, path, drawableState.shapeAppearanceModel, getBoundsAsRectF());
1123+
drawShape(
1124+
canvas,
1125+
fillPaint,
1126+
path,
1127+
drawableState.shapeAppearanceModel,
1128+
drawableState.interpolationStartShapeAppearanceModel,
1129+
getBoundsAsRectF());
11191130
}
11201131

11211132
/**
@@ -1129,7 +1140,12 @@ private void drawFillShape(@NonNull Canvas canvas) {
11291140
@RestrictTo(LIBRARY_GROUP)
11301141
protected void drawStrokeShape(@NonNull Canvas canvas) {
11311142
drawShape(
1132-
canvas, strokePaint, pathInsetByStroke, strokeShapeAppearance, getBoundsInsetByStroke());
1143+
canvas,
1144+
strokePaint,
1145+
pathInsetByStroke,
1146+
strokeShapeAppearance,
1147+
strokeInterpolationStartShapeAppearance,
1148+
getBoundsInsetByStroke());
11331149
}
11341150

11351151
private void prepareCanvasForShadow(@NonNull Canvas canvas) {
@@ -1202,7 +1218,9 @@ public int getShadowOffsetY() {
12021218
* Math.cos(Math.toRadians(drawableState.shadowCompatRotation)));
12031219
}
12041220

1205-
/** @deprecated see {@link ShapeAppearancePathProvider} */
1221+
/**
1222+
* @deprecated see {@link ShapeAppearancePathProvider}
1223+
*/
12061224
@Deprecated
12071225
public void getPathForSize(int width, int height, @NonNull Path path) {
12081226
calculatePathForSize(new RectF(0, 0, width, height), path);
@@ -1226,6 +1244,18 @@ protected final void calculatePathForSize(@NonNull RectF bounds, @NonNull Path p
12261244

12271245
/** Calculates the path that can be used to draw the stroke entirely inside the shape */
12281246
private void calculateStrokePath() {
1247+
updateStrokeShapeAppearanceModels();
1248+
1249+
pathProvider.calculatePath(
1250+
strokeShapeAppearance,
1251+
strokeInterpolationStartShapeAppearance,
1252+
drawableState.interpolation,
1253+
getBoundsInsetByStroke(),
1254+
null,
1255+
pathInsetByStroke);
1256+
}
1257+
1258+
private void updateStrokeShapeAppearanceModels() {
12291259
// Adjust corner radius in order to draw the stroke so that the corners of the background are
12301260
// drawn on top of the edges.
12311261
final float strokeInsetLength = -getStrokeInsetLength();
@@ -1244,13 +1274,20 @@ public CornerSize apply(@NonNull CornerSize cornerSize) {
12441274
}
12451275
});
12461276

1247-
pathProvider.calculatePath(
1248-
strokeShapeAppearance,
1249-
drawableState.interpolationStartShapeAppearanceModel,
1250-
drawableState.interpolation,
1251-
getBoundsInsetByStroke(),
1252-
null,
1253-
pathInsetByStroke);
1277+
strokeInterpolationStartShapeAppearance =
1278+
getInterpolationStartShapeAppearanceModel()
1279+
.withTransformedCornerSizes(
1280+
new CornerSizeUnaryOperator() {
1281+
@NonNull
1282+
@Override
1283+
public CornerSize apply(@NonNull CornerSize cornerSize) {
1284+
// Don't adjust for relative corners they will change by themselves when the
1285+
// bounds change.
1286+
return cornerSize instanceof RelativeCornerSize
1287+
? cornerSize
1288+
: new AdjustedCornerSize(strokeInsetLength, cornerSize);
1289+
}
1290+
});
12541291
}
12551292

12561293
@TargetApi(VERSION_CODES.LOLLIPOP)

0 commit comments

Comments
 (0)