Reputation: 1750
As an Android drawable, this represents a black rectangle with rounded corners.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="20dp" />
<solid android:color="#000000" />
</shape>
However, the corner radius is specified as an absolute 20dp
, so if this same drawable is shown at different sizes, it appears differently. The smaller shape is not just a "scaled down" version of the larger one. Instead, it's "rounder" and the larger one is "more square" because the border radius is a static 20dp
regardless of the size of the drawable.
I want to specify the radius relative to the size of the full drawable, so when it is drawn at different sizes each one appears as a scaled up/down version of the others.
I'm more familiar with CSS, where this can be done in one line:
border-radius: 20%;
I'm surprised to find Android lacking this CSS simplicity. Android does not recognize %
as a unit.
<corners android:radius="20%" />
Is there some simple way to achieve my desired result in Android?
Upvotes: 11
Views: 3046
Reputation: 31
You are right, there is no built in way. But you can achieve it programatically. A time ago I wrote this small class and it works for me
public class CornerDrawable extends GradientDrawable {
private float percent;
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
setCornerRadius(getBounds().height() / percent);
}
@Override
public void setBounds(@NonNull Rect bounds) {
super.setBounds(bounds);
setCornerRadius(getBounds().height() / percent);
}
/**
* Sets the corner radius of each corner to the <code>percent</code> of the height of this drawable. For example, passing
* <i>50</i> will result in a fully rounded side of the target view.
*
* @param percent The percentage of the height of the view to be rounded
*/
public void setCornerRadiusPercent(float percent) {
this.percent = 100 / percent;
}
}
Then you only need to create an instance and configure it the way you want and set it on your target view. For example like this:
//the view you want to apply the corner radius to
View targetView = ...
CornerDrawable cornerDrawable = new CornerDrawable();
//pass your desired percent value
cornerDrawable.setCornerRadiusPercent(20);
// set the solid color from your xml above
cornerDrawable.setColor(getResources().getColor(R.color.black, requireContext().getTheme()));
targetView.setBackground(cornerDrawable);
The only drawback of this is, that you have to do all configuration programmatically, instead of using your drawable xml file.
Upvotes: 2