Skip to content

Commit ca07e5f

Browse files
afohrmancketcham
authored andcommitted
Create OnChangedListener to respond to ShapeAppearanceModel changes and Shapeable interface, and implement it in Chip.
The OnChangedListener provides a callback that MaterialShapeDrawables can use to invalidate themselves when the associated ShapeAppearanceModel changes. This allows for modifying the ShapeAppearanceModel through the get/setShapeAppearance methods that the Shapeable interface exposes without having to update the client to redraw itself. PiperOrigin-RevId: 238703600
1 parent 238b658 commit ca07e5f

5 files changed

Lines changed: 497 additions & 79 deletions

File tree

lib/java/com/google/android/material/chip/Chip.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
import com.google.android.material.resources.TextAppearance;
5757
import com.google.android.material.resources.TextAppearanceFontCallback;
5858
import com.google.android.material.ripple.RippleUtils;
59+
import com.google.android.material.shape.ShapeAppearanceModel;
60+
import com.google.android.material.shape.Shapeable;
5961
import androidx.core.view.ViewCompat;
6062
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
6163
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
@@ -123,7 +125,7 @@
123125
*
124126
* @see ChipDrawable
125127
*/
126-
public class Chip extends AppCompatCheckBox implements Delegate {
128+
public class Chip extends AppCompatCheckBox implements Delegate, Shapeable {
127129

128130
private static final String TAG = "Chip";
129131

@@ -1204,6 +1206,17 @@ public void setChipCornerRadiusResource(@DimenRes int id) {
12041206
}
12051207
}
12061208

1209+
@Override
1210+
public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {
1211+
chipDrawable.setShapeAppearanceModel(shapeAppearanceModel);
1212+
}
1213+
1214+
@NonNull
1215+
@Override
1216+
public ShapeAppearanceModel getShapeAppearanceModel() {
1217+
return chipDrawable.getShapeAppearanceModel();
1218+
}
1219+
12071220
/**
12081221
* @deprecated Use {@link com.google.android.material.shape.ShapeAppearanceModel#setAllCorners(int,
12091222
* int)} instead.

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

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@
6464
* Base drawable class for Material Shapes that handles shadows, elevation, scale and color for a
6565
* generated path.
6666
*/
67-
public class MaterialShapeDrawable extends Drawable implements TintAwareDrawable {
67+
public class MaterialShapeDrawable extends Drawable
68+
implements TintAwareDrawable, ShapeAppearanceModel.OnChangedListener {
6869

6970
private static final float SHADOW_RADIUS_MULTIPLIER = .75f;
7071

@@ -163,6 +164,10 @@ public void onEdgePathCreated(ShapePath edgePath, Matrix transform, int count) {
163164
edgeShadowOperation[count] = edgePath.createShadowCompatOperation(transform);
164165
}
165166
};
167+
168+
// Listens for modifications made in the ShapeAppearanceModel, and requests a redraw if the
169+
// ShapeAppearanceModel has changed.
170+
drawableState.shapeAppearanceModel.addOnChangedListener(this);
166171
}
167172

168173
@Nullable
@@ -190,8 +195,10 @@ private static int modulateAlpha(int paintAlpha, int alpha) {
190195
*
191196
* @param shapeAppearanceModel the desired model.
192197
*/
193-
public void setShapeAppearanceModel(ShapeAppearanceModel shapeAppearanceModel) {
198+
public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {
199+
drawableState.shapeAppearanceModel.removeOnChangedListener(this);
194200
drawableState.shapeAppearanceModel = shapeAppearanceModel;
201+
shapeAppearanceModel.addOnChangedListener(this);
195202
invalidateSelf();
196203
}
197204

@@ -201,6 +208,7 @@ public void setShapeAppearanceModel(ShapeAppearanceModel shapeAppearanceModel) {
201208
*
202209
* @return the current model.
203210
*/
211+
@NonNull
204212
public ShapeAppearanceModel getShapeAppearanceModel() {
205213
return drawableState.shapeAppearanceModel;
206214
}
@@ -524,6 +532,7 @@ public float getInterpolation() {
524532
public void setInterpolation(float interpolation) {
525533
if (drawableState.interpolation != interpolation) {
526534
drawableState.interpolation = interpolation;
535+
pathDirty = true;
527536
invalidateSelf();
528537
}
529538
}
@@ -573,6 +582,30 @@ public void setShadowElevation(int shadowElevation) {
573582
setElevation(shadowElevation);
574583
}
575584

585+
/**
586+
* Returns the shadow vertical offset rendered for shadows when {@link #requiresCompatShadow()} is
587+
* true.
588+
*/
589+
@RestrictTo(LIBRARY_GROUP)
590+
public int getShadowVerticalOffset() {
591+
return drawableState.shadowCompatOffset;
592+
}
593+
594+
/**
595+
* Sets the shadow offset rendered by the fake shadow when {@link #requiresCompatShadow()} is
596+
* true. This can make the shadow appear more on the bottom or top of the view to make a more
597+
* realistic looking shadow depending on the placement of the view on the screen. Normally, if the
598+
* View is positioned further down on the screen, less shadow appears above the View, and more
599+
* shadow appears below it.
600+
*/
601+
@RestrictTo(LIBRARY_GROUP)
602+
public void setShadowVerticalOffset(int shadowOffset) {
603+
if (drawableState.shadowCompatOffset != shadowOffset) {
604+
drawableState.shadowCompatOffset = shadowOffset;
605+
invalidateSelfIgnoreShape();
606+
}
607+
}
608+
576609
/**
577610
* Returns the rotation offset applied to the fake shadow which is drawn when {@link
578611
* #requiresCompatShadow()} is true.
@@ -648,10 +681,15 @@ public void setScale(float scale) {
648681
}
649682
}
650683

684+
@Override
685+
public void onShapeAppearanceModelChanged() {
686+
invalidateSelf();
687+
}
688+
651689
@Override
652690
public void invalidateSelf() {
653691
pathDirty = true;
654-
invalidateSelfIgnoreShape();
692+
super.invalidateSelf();
655693
}
656694

657695
/**
@@ -1128,7 +1166,7 @@ public MaterialShapeDrawableState(
11281166
}
11291167

11301168
public MaterialShapeDrawableState(MaterialShapeDrawableState orig) {
1131-
shapeAppearanceModel = new ShapeAppearanceModel(orig.shapeAppearanceModel);
1169+
shapeAppearanceModel = orig.shapeAppearanceModel;
11321170
elevationOverlayProvider = orig.elevationOverlayProvider;
11331171
strokeWidth = orig.strokeWidth;
11341172
colorFilter = orig.colorFilter;

0 commit comments

Comments
 (0)