How to draw a nested circle programmatically
Here I am using a layer list to draw a nested circle using XML
<item>
<shape android:shape="oval" >
<stroke
android:width="1dp"
android:color="@android:color/holo_orange_light" />
<padding
android:bottom="7dp"
android:left="7dp"
android:right="7dp"
android:top="7dp" />
</shape>
</item>
<item>
<shape android:shape="oval" >
<solid android:color="@color/welcome_bg" />
</shape>
</item>
Not. I want the same nested circle to be used programmatically because I want to dynamically change the color or there is a way to dynamically change the color in the xml above.
Here is my custom view
public class MyView extends EditText {
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
RectF oval1 = new RectF(50, 50, 300, 300);
canvas.drawOval(oval1, paint);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
RectF oval2 = new RectF(55, 55, 295, 295);
canvas.drawOval(oval2, paint);
}
}
thank
source to share
When you use xml, the dimensions specified are in independent dp-density pixels. But your code drawing functions take actual pixels as parameters, and you have to take that into account and calculate your own values ββyourself.
Depending on the device announced, the 1dp screen density will be translated to:
- ldpi (120 dpi) - 0.75 pix
- mdpi (160 dpi) - 1 pix
- hdpi (240 dpi) - 1.5 pix
- xhdpi (320 dpi) - 2 pix
- xxhdpi (480 dpi) - 3 pix
- xxxhdpi (640 dpi) - 4 pix
to compute real pixels px = dp * (dpi / 160)
public class MyView extends EditText {
float mDensityScale;
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public MyView(Context context) {
super(context);
init(context, null, 0);
}
private void init(Context context, AttributeSet attrs, int defStyle)
{
final DisplayMetrics dm = context.getResources().getDisplayMetrics();
mDensityScale = dm.density;
}
private float pix(float dp)
{
return dp * mDensityScale;
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
RectF oval1 = new RectF(pix(50), pix(50), pix(300), pix(300));
canvas.drawOval(oval1, paint);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
RectF oval2 = new RectF(pix(55), pix(55), pix(295), pix(295));
canvas.drawOval(oval2, paint);
}
}
You can read more:
source to share
If you want to change the drawing color while still using xml, you can add an id to the element you want to change:
<item>
<shape android:shape="oval" >
<stroke
android:width="1dp"
android:color="@android:color/holo_orange_light" />
<padding
android:bottom="7dp"
android:left="7dp"
android:right="7dp"
android:top="7dp" />
</shape>
</item>
<item android:id="@+id/circle_inner">
<shape android:shape="oval" >
<solid android:color="@color/welcome_bg" />
</shape>
</item>
And then in your code, get a list of layers to use, and find the corresponding id and change the color:
LayerDrawable layerDrawable = (LayerDrawable) v.getBackground();
GradientDrawable innerCircle = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.circle_inner);
innerCircle.setColor(0xff00ff00);
Note that I am passing in the GradientDrawable because the tag <shape>
is a pointer to ( form tag documentation )
source to share
<item android:id="@+id/circle_outer">
<shape android:shape="oval" >
<stroke
android:width="1dp"
android:color="@android:color/holo_orange_light" />
<padding
android:bottom="7dp"
android:left="7dp"
android:right="7dp"
android:top="7dp" />
</shape>
</item>
<item android:id="@+id/circle_inner">
<shape android:shape="oval" >
<solid android:color="@color/welcome_bg" />
</shape>
</item>
Here I have provided the XML and set their ids and also programmatically changing the color How to change the color of XML elements
LayerDrawable layerDrawable = (LayerDrawable) ctx.getResources().getDrawable(R.drawable.tv_circle);
GradientDrawable innerCircle = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.circle_inner);
GradientDrawable outerCircle = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.circle_outer);
innerCircle.setColor(0xff00ff00);
outerCircle.setStroke(2, Color.BLUE, 0, 10);
Thanks everyone, its works for me and please close it
source to share