Android: Is there a simple way to create rounded corners for a view without having to create a separate drawable each time?
Asked Answered
R

3

6

I have gone through various solutions on the internet, which enable us to create views with rounded corners. Most of them require the use of creating custom views, or to create a drawable in xml or a nine-patch each time we need a rounded corner view.

The problem is that when I implement such views, I need to create a drawable for every such view, even if two views have everything but just the background color in common. This is kind of irritating for me and I've heard the iOS framework provides a good way to create round cornered views. Any help would be much appreciated.

Edit: Along with rounded corners, the press effect of a view and shadows are also among the common styles used. Please let your solution include those effects.

Raspings answered 26/11, 2019 at 8:33 Comment(5)
Have you tried CardView?Pernas
I did, but it's only a view group, and not a proper solution to this issue.Raspings
Maybe check this answer for Android API > 21Subternatural
you can create your custom imageview with rounded corners and use it wherever you wantUnpredictable
@NehaRathore I understand that, but I'm just looking for a solution that is generic and convenient across all views. Also, please point out a few links that explain how you ease this process as an answer. Much appreciated:)Raspings
B
16

With the Material Components Library you can use the MaterialShapeDrawable to draw custom shapes.

For example with a TextView you can do:

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

Then create a MaterialShapeDrawable:

float radius = getResources().getDimension(R.dimen.default_corner_radius);

TextView textView = findViewById(R.id.textview);
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
        .toBuilder()
        .setAllCorners(CornerFamily.ROUNDED,radius)
        .build();

MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
ViewCompat.setBackground(textView,shapeDrawable);

enter image description here

With a simple View:

<View
    android:id="@+id/line"
    android:layout_width="match_parent"
    android:layout_height="4dp"
    android:backgroundTint="@color/..."/>

Then apply the same MaterialShapeDrawable:

View line = findViewById(R.id.line);
ViewCompat.setBackground(line,shapeDrawable);

enter image description here

You can also create different corners:

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

enter image description here

Also most of the components provided by the Material Component Library have a MaterialShapeDrawable as background.
In these cases just use something like (in this example a MaterialCardView).

  MaterialCardView cardView = findViewById(R.id.card);
  cardView.setShapeAppearanceModel(cardView.getShapeAppearanceModel()
        .toBuilder()
        .setBottomLeftCornerSize(...)
        .setBottomEdge(...)
        .build());

It requires the version 1.1.0 of the library. Currently 1.1.0-beta02.

Bahr answered 26/11, 2019 at 15:57 Comment(3)
Thank you, I feel this is the best solution thus far. I suppose you can also add shadows and press effects this wayRaspings
@Raspings I've update the answer with an useful link for the shaping. Here the API for the MaterialShapeDrawable.Bahr
This is nice, may I ask how you keep yourself updated on the various methods of doing stuff on android?Raspings
M
0

You can use Gradient drawable for your views programmatically and can set that view as background

 GradientDrawable getRoundedCornerView(int shapetype,int color,float radius){
     GradientDrawable shape = new GradientDrawable();
     shape.setShape(shapetype); //GradientDrawable.RECTANGLE for rectangle
     shape.setColor(color);
     shape.setCornerRadius(radius);
retrun shape;
}
Marinetti answered 26/11, 2019 at 10:53 Comment(0)
K
-1

If you just want to change the color of the background, you can use backgroundTint

For example:


    <ImageView
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@drawable/background"
        app:backgroundTint="#F00"
        />

Please note: I'm using app:backgroundTint here, by using app prefix, AppCompat Views (AppCompatImageView, AppCompatButton, etc) can read this attribute and tint the background on pre-lollipop Android devices, but you should make sure you are using appcompat library.

The universal solution:

On second thought, I come up with a method: you can create a LayoutInflater.Factory and replace all the views(imageView, TextView, etc) with your own custom view which takes corner radius and color as background, just like AppCompat library.

Kaftan answered 26/11, 2019 at 8:46 Comment(4)
Hi Zumi, I'm not sure how a background tint can help with rounded corners.Raspings
Well, you said "even if two views have everything but just the background color in common"in your question so I thought all your view will have same radius but with different color.Kaftan
Then you can create one rounded corner drawable as background and use backgroundTint to control the background color of the view.Kaftan
Oh, maybe that can help. There could be some alpha composition done when a tint is used though. Thank you.Raspings

© 2022 - 2024 — McMap. All rights reserved.