Skip to content

Commit 08c40d8

Browse files
committed
[TextInputLayout] Added method to set corner family programmatically and a setShapeAppearanceModel method for greater customizability of the box background shape.
Resolves #1957 PiperOrigin-RevId: 470826160
1 parent b8e1b57 commit 08c40d8

File tree

3 files changed

+313
-24
lines changed

3 files changed

+313
-24
lines changed

lib/java/com/google/android/material/textfield/TextInputLayout.java

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
import com.google.android.material.internal.ViewUtils;
9999
import com.google.android.material.motion.MotionUtils;
100100
import com.google.android.material.resources.MaterialResources;
101+
import com.google.android.material.shape.CornerFamily;
102+
import com.google.android.material.shape.CornerTreatment;
101103
import com.google.android.material.shape.MaterialShapeDrawable;
102104
import com.google.android.material.shape.ShapeAppearanceModel;
103105
import java.lang.annotation.Retention;
@@ -1220,6 +1222,46 @@ public int getBoxBackgroundColor() {
12201222
return boxBackgroundColor;
12211223
}
12221224

1225+
/**
1226+
* Sets the {@link ShapeAppearanceModel} of the text field's box background.
1227+
*
1228+
* @param shapeAppearanceModel the desired shape appearance model.
1229+
* @see #getShapeAppearanceModel()
1230+
*/
1231+
public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {
1232+
if (boxBackground != null && boxBackground.getShapeAppearanceModel() != shapeAppearanceModel) {
1233+
this.shapeAppearanceModel = shapeAppearanceModel;
1234+
applyBoxAttributes();
1235+
}
1236+
}
1237+
1238+
/**
1239+
* Returns the {@link ShapeAppearanceModel} of the text field's box background.
1240+
*
1241+
* @see #setShapeAppearanceModel(ShapeAppearanceModel)
1242+
*/
1243+
@NonNull
1244+
public ShapeAppearanceModel getShapeAppearanceModel() {
1245+
return shapeAppearanceModel;
1246+
}
1247+
1248+
/**
1249+
* Sets the box's corner family for all corners of the text field.
1250+
*
1251+
* @param cornerFamily the {@link CornerFamily} to be used. May be one of {@link
1252+
* CornerFamily#ROUNDED} or {@link CornerFamily#CUT}.
1253+
*/
1254+
public void setBoxCornerFamily(@CornerFamily int cornerFamily) {
1255+
shapeAppearanceModel =
1256+
shapeAppearanceModel.toBuilder()
1257+
.setTopLeftCorner(cornerFamily, shapeAppearanceModel.getTopLeftCornerSize())
1258+
.setTopRightCorner(cornerFamily, shapeAppearanceModel.getTopRightCornerSize())
1259+
.setBottomLeftCorner(cornerFamily, shapeAppearanceModel.getBottomLeftCornerSize())
1260+
.setBottomRightCorner(cornerFamily, shapeAppearanceModel.getBottomRightCornerSize())
1261+
.build();
1262+
applyBoxAttributes();
1263+
}
1264+
12231265
/**
12241266
* Set the resources used for the box's corner radii.
12251267
*
@@ -3040,9 +3082,8 @@ public void setExpandedHintEnabled(boolean enabled) {
30403082
public void onRtlPropertiesChanged(int layoutDirection) {
30413083
super.onRtlPropertiesChanged(layoutDirection);
30423084
boolean isLayoutDirectionRtl = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL;
3043-
if (isLayoutDirectionRtl != areCornerRadiiRtl) {
3085+
if (isLayoutDirectionRtl != areCornerRadiiRtl) {
30443086
// Switch corner radius values from LTR to RTL or vice versa.
3045-
boolean shouldCornersBeRtl = isLayoutDirectionRtl && !areCornerRadiiRtl;
30463087
float boxCornerRadiusTopLeft =
30473088
shapeAppearanceModel.getTopLeftCornerSize().getCornerSize(tmpRectF);
30483089
float boxCornerRadiusTopRight =
@@ -3051,12 +3092,29 @@ public void onRtlPropertiesChanged(int layoutDirection) {
30513092
shapeAppearanceModel.getBottomLeftCornerSize().getCornerSize(tmpRectF);
30523093
float boxCornerRadiusBottomRight =
30533094
shapeAppearanceModel.getBottomRightCornerSize().getCornerSize(tmpRectF);
3054-
setBoxCornerRadii(
3055-
shouldCornersBeRtl ? boxCornerRadiusTopLeft : boxCornerRadiusTopRight,
3056-
shouldCornersBeRtl ? boxCornerRadiusTopRight : boxCornerRadiusTopLeft,
3057-
shouldCornersBeRtl ? boxCornerRadiusBottomLeft : boxCornerRadiusBottomRight,
3058-
shouldCornersBeRtl ? boxCornerRadiusBottomRight : boxCornerRadiusBottomLeft);
3059-
}
3095+
CornerTreatment topLeftTreatment =
3096+
shapeAppearanceModel.getTopLeftCorner();
3097+
CornerTreatment topRightTreatment =
3098+
shapeAppearanceModel.getTopRightCorner();
3099+
CornerTreatment bottomLeftTreatment =
3100+
shapeAppearanceModel.getBottomLeftCorner();
3101+
CornerTreatment bottomRightTreatment =
3102+
shapeAppearanceModel.getBottomRightCorner();
3103+
3104+
ShapeAppearanceModel newShapeAppearanceModel =
3105+
ShapeAppearanceModel.builder()
3106+
.setTopLeftCorner(topRightTreatment)
3107+
.setTopRightCorner(topLeftTreatment)
3108+
.setBottomLeftCorner(bottomRightTreatment)
3109+
.setBottomRightCorner(bottomLeftTreatment)
3110+
.setTopLeftCornerSize(boxCornerRadiusTopRight)
3111+
.setTopRightCornerSize(boxCornerRadiusTopLeft)
3112+
.setBottomLeftCornerSize(boxCornerRadiusBottomRight)
3113+
.setBottomRightCornerSize(boxCornerRadiusBottomLeft)
3114+
.build();
3115+
areCornerRadiiRtl = isLayoutDirectionRtl;
3116+
setShapeAppearanceModel(newShapeAppearanceModel);
3117+
}
30603118
}
30613119

30623120
@Override

tests/javatests/com/google/android/material/testutils/TextInputLayoutActions.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@
3131
import android.widget.AutoCompleteTextView;
3232
import androidx.annotation.ColorInt;
3333
import androidx.annotation.DimenRes;
34+
import androidx.annotation.NonNull;
3435
import androidx.test.espresso.UiController;
3536
import androidx.test.espresso.ViewAction;
3637
import androidx.test.espresso.matcher.ViewMatchers;
3738
import com.google.android.material.internal.CheckableImageButton;
39+
import com.google.android.material.shape.CornerFamily;
40+
import com.google.android.material.shape.ShapeAppearanceModel;
3841
import com.google.android.material.testapp.R;
3942
import com.google.android.material.textfield.TextInputLayout;
4043
import org.hamcrest.Matcher;
@@ -639,6 +642,49 @@ public void perform(UiController uiController, View view) {
639642
};
640643
}
641644

645+
/** Sets the {@link ShapeAppearanceModel} of the text field's box background. */
646+
public static ViewAction setShapeAppearanceModel(
647+
@NonNull ShapeAppearanceModel shapeAppearanceModel) {
648+
return new ViewAction() {
649+
@Override
650+
public Matcher<View> getConstraints() {
651+
return isAssignableFrom(TextInputLayout.class);
652+
}
653+
654+
@Override
655+
public String getDescription() {
656+
return "Sets the box's shape appearance";
657+
}
658+
659+
@Override
660+
public void perform(UiController uiController, View view) {
661+
TextInputLayout layout = (TextInputLayout) view;
662+
layout.setShapeAppearanceModel(shapeAppearanceModel);
663+
}
664+
};
665+
}
666+
667+
/** Sets the corner family for all corners of the text field. */
668+
public static ViewAction setBoxCornerFamily(@CornerFamily final int cornerFamily) {
669+
return new ViewAction() {
670+
@Override
671+
public Matcher<View> getConstraints() {
672+
return isAssignableFrom(TextInputLayout.class);
673+
}
674+
675+
@Override
676+
public String getDescription() {
677+
return "Sets the box's corner family";
678+
}
679+
680+
@Override
681+
public void perform(UiController uiController, View view) {
682+
TextInputLayout layout = (TextInputLayout) view;
683+
layout.setBoxCornerFamily(cornerFamily);
684+
}
685+
};
686+
}
687+
642688
public static ViewAction setBoxCornerRadii(
643689
final float topLeftCornerRadius,
644690
final float topRightCornerRadius,

0 commit comments

Comments
 (0)