How to make a circular drawable with stroke, programmatically?
You can do this programmatically as
In YourActivity.XMl
, Set-up an ImageView
as usual.
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/id1"
android:src="@mipmap/ic_launcher_round"
android:padding="15dp"/>
And in your MainActivity.java
ImageView iV = (ImageView) findViewById(R.id.id1);
int strokeWidth = 5;
int strokeColor = Color.parseColor("#03dc13");
int fillColor = Color.parseColor("#ff0000");
GradientDrawable gD = new GradientDrawable();
gD.setColor(fillColor);
gD.setShape(GradientDrawable.OVAL);
gD.setStroke(strokeWidth, strokeColor);
iV.setBackground(gD);
setColor
here sets the background color and setStroke
sets the stroke width and stroke color.
I have created some local variables for color, width etc to make it more easy to understand.
Result
More you increase the padding, more will the size of circle increase.
Related videos on Youtube
android developer
Really like to develop Android apps & libraries on my spare time. Github website: https://github.com/AndroidDeveloperLB/ My spare time apps: https://play.google.com/store/apps/developer?id=AndroidDeveloperLB
Updated on June 04, 2022Comments
-
android developer almost 2 years
Background
I'm trying to have a filled circle, with a stroke of certain color and width, and an image inside.
This can easily be done in XML, as such (this is just a sample) :
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="oval"> <size android:width="120dp" android:height="120dp"/> <solid android:color="#ffff0000"/> <stroke android:width="3dp" android:color="#ff00ff00"/> </shape> </item> <item android:width="60dp" android:height="60dp" android:drawable="@android:drawable/btn_star" android:gravity="center"/> </layer-list>
The problem
I need to have certain properties of the above to change programmatically, so I can't use the XML file, but the idea is still the same.
Thing is, I can't find an easy way to put a stroke on an OvalShape drawable, as done in XML. I can't find the function to do it.
What I tried
There are solutions out there here on StackOverflow, but I couldn't find one that works well. Only one I've found is here, but its stroke line is being cut .
I have, however, partially succeeded in one way to solve this, by using an XML just for the stroke itself:
stroke_drawable.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <stroke android:width="4dp" android:color="@android:color/white"/> </shape>
code:
final int strokeDrawableResId = R.drawable.stroke_drawable; Drawable innerDrawable = ResourcesCompat.getDrawable(getResources(), ..., null); final Drawable strokeDrawable = ResourcesCompat.getDrawable(getResources(), strokeDrawableResId, null); ShapeDrawable biggerCircle = new ShapeDrawable(new OvalShape()); int size = ...; biggerCircle.setIntrinsicHeight(size); biggerCircle.setIntrinsicWidth(size); biggerCircle.getPaint().setColor(0xffff0000); biggerCircle.setBounds(new Rect(0, 0, size, size)); LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{biggerCircle, strokeDrawable, innerDrawable}); ImageView imageView = findViewById(R.id.imageView); imageView.setImageDrawable(layerDrawable);
It works, but it's not fully programmatically (stroke is defined in XML).
The question
How to change the code to be fully programmatic ?
EDIT: I tried what was suggested here, yet instead of an additional drawable for a background, since I needed it all in one drawable, I used LayerDrawable:
Drawable innerDrawable = ResourcesCompat.getDrawable(getResources(), android.R.drawable.btn_star, null); int strokeWidth = 5; int strokeColor = Color.parseColor("#ff0000ff"); int fillColor = Color.parseColor("#ffff0000"); GradientDrawable gD = new GradientDrawable(); gD.setColor(fillColor); gD.setShape(GradientDrawable.OVAL); gD.setStroke(strokeWidth, strokeColor); LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{gD, innerDrawable}); ImageView imageView = findViewById(R.id.imageView); imageView.setImageDrawable(layerDrawable);
This works, but for some reason the drawable inside (the star) is being stretched:
-
TacB0sS over 6 yearsbest answer I've seen all day... Thanks