How to programmatically round corners and set random background colors

135,566

Solution 1

Instead of setBackgroundColor, retrieve the background drawable and set its color:

v.setBackgroundResource(R.drawable.tags_rounded_corners);

GradientDrawable drawable = (GradientDrawable) v.getBackground();
if (i % 2 == 0) {
  drawable.setColor(Color.RED);
} else {
  drawable.setColor(Color.BLUE);
}

Also, you can define the padding within your tags_rounded_corners.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <corners android:radius="4dp" />
  <padding
    android:top="2dp"
    android:left="2dp"
    android:bottom="2dp"
    android:right="2dp" />
</shape> 

Solution 2

Total programmatic approach to set rounded corners and add random background color to a View. I have not tested the code, but you get the idea.

 GradientDrawable shape =  new GradientDrawable();
 shape.setCornerRadius( 8 );

 // add some color
 // You can add your random color generator here
 // and set color
 if (i % 2 == 0) {
  shape.setColor(Color.RED);
 } else {
  shape.setColor(Color.BLUE);
 }

 // now find your view and add background to it
 View view = (LinearLayout) findViewById( R.id.my_view );
 view.setBackground(shape);

Here we are using gradient drawable so that we can make use of GradientDrawable#setCornerRadius because ShapeDrawable DOES NOT provide any such method.

Solution 3

I think the fastest way to do this is:

GradientDrawable gradientDrawable = new GradientDrawable(
            GradientDrawable.Orientation.TOP_BOTTOM, //set a gradient direction 
            new int[] {0xFF757775,0xFF151515}); //set the color of gradient
gradientDrawable.setCornerRadius(10f); //set corner radius

//Apply background to your view
View view = (RelativeLayout) findViewById( R.id.my_view );
if(Build.VERSION.SDK_INT>=16)
     view.setBackground(gradientDrawable);
else view.setBackgroundDrawable(gradientDrawable);    

Solution 4

You can better achieve it by using the DrawableCompat like this:

Drawable backgroundDrawable = view.getBackground();             
DrawableCompat.setTint(backgroundDrawable, newColor);

Solution 5

As the question has already been answered. But I have a little tweak

GradientDrawable drawable = (GradientDrawable) ContextCompat.getDrawable(context, R.drawable.YOUR_DRAWABLE).mutate();

you can change corner radius with:

drawable.setCornerRadius(YOUR_VALUE);

Change color with:

drawable.setColor(Color.YOUR_COLOR);

A mutable drawable is guaranteed to not share its state with any other drawable. So if you change radius without using mutate(), you are likely to change others state too. It is best suitable for specific views.

At last don't forget to set the drawable.

this.setBackground(drawable);
Share:
135,566
John Moffitt
Author by

John Moffitt

Updated on January 23, 2021

Comments

  • John Moffitt
    John Moffitt over 3 years

    I'd like to round the corners of a view and also change the color of the view based on the contents at runtime.

    TextView v = new TextView(context);
    v.setText(tagsList.get(i));
    if(i%2 == 0){
        v.setBackgroundColor(Color.RED);
    }else{
        v.setBackgroundColor(Color.BLUE);
    }
    
    v.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
    v.setPadding(twoDP, twoDP, twoDP, twoDP);               
    v.setBackgroundResource(R.drawable.tags_rounded_corners);
    

    I was hoping setting a drawable and color would overlap, but they do not. Whichever one I execute second is the resulting background.

    Is there any way to programmatically create this view, keeping in mind that the background color won't be decided until runtime?

    edit: I'm only swapping between red and blue now for testing. Later the color will be choosable by the user.

    edit:

    tags_rounded_corners.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <corners 
             android:bottomRightRadius="2dp" 
             android:bottomLeftRadius="2dp" 
             android:topLeftRadius="2dp" 
             android:topRightRadius="2dp"/>
    </shape>
    
  • umesh
    umesh over 10 years
    shape.setCornerRadii(corners); its very useful
  • Akhil Dad
    Akhil Dad over 9 years
    Perect answe! it worked with strock as well, but can we make this using something like colorDrawable = resources.getDrawable(R.drawable.x_sd_circle); colorDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); if we are not having an border. But in case of border can you let me know the PorterDuff.Mode so that stroke color won't change
  • Tim Malseed
    Tim Malseed over 9 years
    I was going to use this, but I'm having a stroke.
  • Raj
    Raj over 8 years
    How to add background color as well via XML?
  • sonavolob
    sonavolob over 8 years
    If "v" is the TextView than v.getBackground() will cast "java.lang.ClassCastException: android.graphics.drawable.StateListDrawable cannot be cast to android.graphics.drawable.GradientDrawable" Was this realy working back in '13?
  • Cimlman
    Cimlman over 8 years
    Consider using PaintDrawable instead of GradientDrawable. It supports rounded corners and just a single color which seems to be more appropriate than a gradient.
  • Adnan
    Adnan about 8 years
    @sonavolob you're right. it gives ClassCastException
  • Bot
    Bot almost 8 years
    The perfect solution! Thank you!
  • Ankit
    Ankit almost 8 years
    Superb Answer! Thanks
  • Riz
    Riz almost 8 years
    Excellent Solution
  • Pierre
    Pierre over 7 years
    This works well! I use it in Xamarin. var pd = new PaintDrawable(BackgroundColor); pd.SetCornerRadius(15); myView.Background = pd;
  • The Unknown Dev
    The Unknown Dev about 7 years
    Nice quick solution, but note that it requires API Minimum Level 16
  • Amir Ziarati
    Amir Ziarati about 7 years
    1+ for getbackground() trick. cuz you cant make one corner rounded with GradientDrawable but using getBackground you can ;)
  • Dr.jacky
    Dr.jacky over 6 years
    I have a XML layout which have just one RelativeLayout. First inflated it. Then setBackgroundResource. Then getBackground. And in this line: java.lang.ClassCastException: android.graphics.drawable.LayerDrawable cannot be cast to android.graphics.drawable.GradientDrawable
  • Anonymous-E
    Anonymous-E almost 5 years
    how to set the corner radius just for one side?
  • Jawad Zeb
    Jawad Zeb over 4 years
    Gradient Drawable is working with TextView and RelativeLayout, use the same XML shape drawable, don't forget to set property of textview in the xml android:background="@drawable/tags_rounded_corners"
  • Adam Pisula
    Adam Pisula over 4 years
    @Anonymous-E I advise you looking up GradientDrawable.setCornerRadii() function.
  • Duc Trung Mai
    Duc Trung Mai almost 4 years
    Works perfectly
  • Androidcoder
    Androidcoder over 2 years
    Setting rounded corners was the only bit of code in my game that was not programmatic until seeing this solution.