How to programmatically round corners and set random background colors

AndroidAndroid LayoutBackgroundAndroid ViewRounded Corners

Android Problem Overview


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>

Android Solutions


Solution 1 - Android

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 - Android

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 - Android

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 - Android

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

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

Solution 5 - Android

If you are not having a stroke you can use

colorDrawable = resources.getDrawable(R.drawable.x_sd_circle); 

colorDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);

but this will also change stroke color

Solution 6 - Android

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);

Solution 7 - Android

You can dynamically change color of any items ( layout, textview ) . Try below code to set color programmatically in layout

in activity.java file


String quote_bg_color = "#FFC107"
quoteContainer= (LinearLayout)view.findViewById(R.id.id_quotecontainer);
quoteContainer.setBackgroundResource(R.drawable.layout_round);
GradientDrawable drawable = (GradientDrawable) quoteContainer.getBackground();
drawable.setColor(Color.parseColor(quote_bg_color));

create layout_round.xml in drawable folder

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorPrimaryLight"/>
    <stroke android:width="0dp" android:color="#B1BCBE" />
    <corners android:radius="10dp"/>
    <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

layout in activity.xml file

<LinearLayout
        android:id="@+id/id_quotecontainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

----other components---

</LinearLayout>


Solution 8 - Android

Here's an example using an extension. This assumes the view has the same width and height.

Need to use a layout change listener to get the view size. Then you can just call this on a view like this myView.setRoundedBackground(Color.WHITE)

fun View.setRoundedBackground(@ColorInt color: Int) {
    addOnLayoutChangeListener(object: View.OnLayoutChangeListener {
        override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {

            val shape = GradientDrawable()
            shape.cornerRadius = measuredHeight / 2f
            shape.setColor(color)

            background = shape

            removeOnLayoutChangeListener(this)
        }
    })
}

Solution 9 - Android

Copying @cimlman's comment into a top-level answer for more visibility:

PaintDrawable(Color.CYAN).apply {
  setCornerRadius(24f)
}

FYI: ShapeDrawable (and its subtype, PaintDrawable) uses default intrinsic width and height of 0. If the drawable does not show up in your usecase, you might have to set the dimensions manually:

PaintDrawable(Color.CYAN).apply {
  intrinsicWidth = -1
  intrinsicHeight = -1
  setCornerRadius(24f)
}

-1 is a magic constant which indicates that a Drawable has no intrinsic width and height of its own (Source).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn MoffittView Question on Stackoverflow
Solution 1 - AndroidchiukiView Answer on Stackoverflow
Solution 2 - AndroidJaydeepWView Answer on Stackoverflow
Solution 3 - AndroidNoleshView Answer on Stackoverflow
Solution 4 - AndroidAlécio CarvalhoView Answer on Stackoverflow
Solution 5 - AndroidAkhil DadView Answer on Stackoverflow
Solution 6 - AndroidsudaynView Answer on Stackoverflow
Solution 7 - AndroidpassionatedevopsView Answer on Stackoverflow
Solution 8 - AndroidMarkymarkView Answer on Stackoverflow
Solution 9 - AndroidSaketView Answer on Stackoverflow