Search code examples
androidandroid-edittextandroid-themeandroid-stylesmaterial-components-android

How to apply shapeAppreanace in EditText and TextView using Material Design in Android


I want to design a TextView and EditText with round corner.

enter image description here

There is one straight forward solution for this. Using custom shape background. But since material design 1.1.0 introduces shapeAppearance theme attribute to apply a different shape to the corner which works fine for all Material components like MaterialButton, BottomSheet, MaterialCardView, etc. But it does not work for EditText and TextView. I tried using MaterialTextView as well but it did not work. This how I am setting up style for EditText which is similar to TextView also.

<style name="ThemeOverlay.Chat" parent="AppTheme">
        <item name="editTextStyle">@style/Overlay.Chat.EditText</item>
    </style>


    <style name="Overlay.Chat.EditText" parent="Widget.AppCompat.EditText">
        <item name="shapeAppearanceOverlay">@style/ShapeAppearance.Overlay.FullRound</item>
    </style>

    <style name="ShapeAppearance.Overlay.FullRound" parent="ShapeAppearance.MaterialComponents.LargeComponent">
        <item name="cornerSize">50dp</item>
    </style>

Solution

  • You can apply the MaterialShapeDrawable introduced by the Material Components Library also to a TextView or EditText.
    In this case you can't use the shapeAppearanceOverlay attribute in your layout or style because these components don't have a MaterialShapeDrawable defined by default as the MaterialButton, MaterialCardView.
    But you apply the same ShapeAppearence programmatically.

    For example:

    <TextView
        android:id="@+id/textview"
        android:backgroundTint="@color/secondaryColor"
        ../>
    

    Programmatically you can use something like:

    float radius = getResources().getDimension(R.dimen.default_corner_radius);
    TextView textView = findViewById(R.id.textview);
    

    Define the ShapeAppearanceModel with rounded corners:

    ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
            .toBuilder()
            .setAllCorners(CornerFamily.ROUNDED,radius)
            .build();
    

    Create a MaterialShapeDrawable with this ShapeAppearanceModel:

    MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
    

    Apply this background to your view:

    ViewCompat.setBackground(textView,shapeDrawable);
    

    enter image description here

    You can achieve the same behavior with an EditText (but you can also use a TextInputLayout in this case):

    Define in your layout:

        <EditText
            android:id="@+id/edittext"
            android:paddingLeft="4dp"
            android:drawableLeft="@drawable/ic_add_24px"
            android:drawableTint="@color/..."
            android:hint="@string/...."
            ..>
    

    Then apply the MaterialShapeDrawable:

    EditText editText = findViewById(R.id.edittext);
    //Apply the rounded corners 
    ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
                    .toBuilder()
                    .setAllCorners(CornerFamily.ROUNDED,radius)
                    .build();
    
    MaterialShapeDrawable shapeDrawable = 
                new MaterialShapeDrawable(shapeAppearanceModel);
    //Fill the background color
    shapeDrawable.setFillColor(ContextCompat.getColorStateList(this,R.color....));
    //You can also apply a stroke
    shapeDrawable.setStroke(2.0f, ContextCompat.getColor(this,R.color....));
    
    //Apply the shapeDrawable to the background.
    ViewCompat.setBackground(editText,shapeDrawable);
    

    enter image description hereenter image description here

    If you would like to use ShapeAppareace defined in the styles you can use the different ShapeAppearanceModel constructors. For example:

    ShapeAppearanceModel shapeAppearanceModel =
                ShapeAppearanceModel.builder( this,
                        R.style.ShapeAppearance_MaterialComponents_MediumComponent,
                        R.style.ShapeOverlay).build();
    

    with:

    <style name="ShapeOverlay">
        <item name="cornerSize">16dp</item>
    </style>