3737import com .google .android .material .button .MaterialButton ;
3838import com .google .android .material .internal .DescendantOffsetUtils ;
3939import com .google .android .material .internal .ThemeEnforcement ;
40+ import com .google .android .material .shape .ShapeAppearanceModel ;
4041import androidx .coordinatorlayout .widget .CoordinatorLayout ;
4142import androidx .coordinatorlayout .widget .CoordinatorLayout .AttachedBehavior ;
4243import androidx .coordinatorlayout .widget .CoordinatorLayout .Behavior ;
7071 */
7172public class ExtendedFloatingActionButton extends MaterialButton implements AttachedBehavior {
7273
74+ private static final int DEF_STYLE_RES =
75+ R .style .Widget_MaterialComponents_ExtendedFloatingActionButton_Icon ;
76+
7377 private static final int ANIM_STATE_NONE = 0 ;
7478 private static final int ANIM_STATE_HIDING = 1 ;
7579 private static final int ANIM_STATE_SHOWING = 2 ;
@@ -96,6 +100,7 @@ public class ExtendedFloatingActionButton extends MaterialButton implements Atta
96100 @ Nullable private ArrayList <AnimatorListener > extendListeners ;
97101
98102 private boolean isExtended = true ;
103+ private boolean isUsingPillCorner = true ;
99104
100105 /**
101106 * Callback to be invoked when the visibility or the state of an ExtendedFloatingActionButton
@@ -147,20 +152,14 @@ public ExtendedFloatingActionButton(Context context, @Nullable AttributeSet attr
147152
148153 @ SuppressWarnings ("initialization" )
149154 public ExtendedFloatingActionButton (
150- Context context ,
151- @ Nullable AttributeSet attrs ,
152- int defStyleAttr ) {
155+ Context context , @ Nullable AttributeSet attrs , int defStyleAttr ) {
153156 super (context , attrs , defStyleAttr );
154157 behavior = new ExtendedFloatingActionButtonBehavior <>(context , attrs );
155158 userSetVisibility = getVisibility ();
156159
157160 TypedArray a =
158161 ThemeEnforcement .obtainStyledAttributes (
159- context ,
160- attrs ,
161- R .styleable .ExtendedFloatingActionButton ,
162- defStyleAttr ,
163- R .style .Widget_MaterialComponents_ExtendedFloatingActionButton_Icon );
162+ context , attrs , R .styleable .ExtendedFloatingActionButton , defStyleAttr , DEF_STYLE_RES );
164163
165164 showMotionSpec =
166165 MotionSpec .createFromAttribute (
@@ -176,6 +175,11 @@ public ExtendedFloatingActionButton(
176175 context , a , R .styleable .ExtendedFloatingActionButton_shrinkMotionSpec );
177176
178177 a .recycle ();
178+
179+ ShapeAppearanceModel shapeAppearanceModel =
180+ new ShapeAppearanceModel (
181+ context , attrs , defStyleAttr , DEF_STYLE_RES , ShapeAppearanceModel .PILL );
182+ setShapeAppearanceModel (shapeAppearanceModel );
179183 }
180184
181185 @ Override
@@ -191,9 +195,10 @@ protected void onAttachedToWindow() {
191195 @ Override
192196 protected void onMeasure (int widthMeasureSpec , int heightMeasureSpec ) {
193197 super .onMeasure (widthMeasureSpec , heightMeasureSpec );
194- // TODO: This must be removed if we want cornerRadius values to be controlled by MotionSpec
195- // Override any corner radius set by the user
196- setCornerRadius (getAdjustedRadius (getMeasuredHeight ()));
198+
199+ if (isUsingPillCorner ) {
200+ getShapeAppearanceModel ().setCornerRadius (getAdjustedRadius (getMeasuredHeight ()));
201+ }
197202 }
198203
199204 @ NonNull
@@ -202,6 +207,23 @@ public Behavior<ExtendedFloatingActionButton> getBehavior() {
202207 return behavior ;
203208 }
204209
210+ @ Override
211+ public void setShapeAppearanceModel (@ NonNull ShapeAppearanceModel shapeAppearanceModel ) {
212+ isUsingPillCorner = shapeAppearanceModel .isUsingPillCorner ();
213+ super .setShapeAppearanceModel (shapeAppearanceModel );
214+ }
215+
216+ @ Override
217+ public void setCornerRadius (int cornerRadius ) {
218+ isUsingPillCorner = cornerRadius == ShapeAppearanceModel .PILL ;
219+ if (isUsingPillCorner ) {
220+ cornerRadius = getAdjustedRadius (getMeasuredHeight ());
221+ } else if (cornerRadius < 0 ) {
222+ cornerRadius = 0 ;
223+ }
224+ super .setCornerRadius (cornerRadius );
225+ }
226+
205227 @ Override
206228 public void setVisibility (int visibility ) {
207229 internalSetVisibility (visibility , true );
@@ -721,7 +743,7 @@ private AnimatorSet createAnimator(@NonNull MotionSpec spec) {
721743 animators .add (spec .getAnimator ("height" , this , HEIGHT ));
722744 }
723745
724- if (spec .hasPropertyValues ("cornerRadius" )) {
746+ if (spec .hasPropertyValues ("cornerRadius" ) && ! isUsingPillCorner ) {
725747 animators .add (spec .getAnimator ("cornerRadius" , this , CORNER_RADIUS ));
726748 }
727749
@@ -757,16 +779,6 @@ private AnimatorSet createShrinkExtendAnimator(@NonNull MotionSpec spec, boolean
757779 spec .setPropertyValues ("height" , heightValues );
758780 }
759781
760- if (spec .hasPropertyValues ("cornerRadius" )) {
761- PropertyValuesHolder [] cornerRadiusValues = spec .getPropertyValues ("cornerRadius" );
762- if (shrinking ) {
763- cornerRadiusValues [0 ].setFloatValues (getCornerRadius (), getAdjustedRadius (collapsedSize ));
764- } else {
765- cornerRadiusValues [0 ].setFloatValues (getCornerRadius (), getAdjustedRadius (getHeight ()));
766- }
767- spec .setPropertyValues ("cornerRadius" , cornerRadiusValues );
768- }
769-
770782 return createAnimator (spec );
771783 }
772784
@@ -915,12 +927,17 @@ public Float get(View object) {
915927 new Property <View , Float >(Float .class , "cornerRadius" ) {
916928 @ Override
917929 public void set (View object , Float value ) {
918- ((ExtendedFloatingActionButton ) object ).setCornerRadius (value .intValue ());
930+ ((ExtendedFloatingActionButton ) object )
931+ .getShapeAppearanceModel ()
932+ .setCornerRadius (value .intValue ());
919933 }
920934
921935 @ Override
922936 public Float get (View object ) {
923- return (float ) ((ExtendedFloatingActionButton ) object ).getCornerRadius ();
937+ return ((ExtendedFloatingActionButton ) object )
938+ .getShapeAppearanceModel ()
939+ .getTopRightCorner ()
940+ .getCornerSize ();
924941 }
925942 };
926943
0 commit comments