I have a custom view that is a circle. Here is the code for my CircleView:
public class CircleView extends View {
private static final int START_ANGLE_POINT = 90;
private final Paint paint;
private final RectF rect;
private float angle;
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
final int strokeWidth = 40;
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(strokeWidth);
//Circle color
paint.setColor(Color.RED);
rect = new RectF(strokeWidth, strokeWidth, 1000 + strokeWidth, 1000 + strokeWidth);
//Initial angle is zero
angle = 0;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(rect, START_ANGLE_POINT, angle, false, paint);
}
public float getAngle() {
return angle;
}
public void setAngle(float angle) {
this.angle = angle;
} }
and here is how I declare it in the xml layout of an activity:
<com.my_package.ui.recording.CircleView
android:id="#+id/circleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
All standard stuff. This is how my custom image looks like
Now, I want to place an imageView in the centre on the circleView? Does any one know how can I achieve that?
This is ideally what I would like to end up with:
Thank you in advance.
If you aren't set on using an ImageView and really just want to draw the bitmap in the center then have a look at canvas' drawBitmap method. This will allow you to draw it however/wherever you want.
I have a box in my Android application, which needs to be transparent, while filling the rest of the frame outside the box with a specific colour.
How exactly could this be done in Canvas or OpenCV or any other means?
Here is an example showing a circle with transparent hole you can implement the same using Rectangle instead of circle.
public class OverlayWithHoleImageView extends ImageView {
private RectF circleRect;
private int radius;
public OverlayWithHoleImageView(Context context, AttributeSet attrs) {
super(context, attrs);
//In versions > 3.0 need to define layer Type
if (android.os.Build.VERSION.SDK_INT >= 11)
{
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
public void setCircle(RectF rect, int radius) {
this.circleRect = rect;
this.radius = radius;
//Redraw after defining circle
postInvalidate();
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(circleRect != null) {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(getResources().getColor(android.R.color.black));
paint.setStyle(Paint.Style.FILL);
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRoundRect(circleRect, radius, radius, paint);
}
}
}
reference : Medium
My task is Drawing a Circle Diagram.
I have 4 arcs.
On each arc, I have 2 values to make View Animate.
this image
will show you more detail.
Can Anyone Suggest me the Animation should I use for each value?
And how can I make it Animate by Specific Angle?
Edit: I upload .gif file for more detail.
You can make a custom View and a custom animation. Override the applyTransformation() Method in the custom Animation to apply the transformation.
public class ArcView extends View {
private final Paint mPaint;
private final RectF mRect;
private float arcAngle;
public ArcView(Context context, AttributeSet attrs) {
super(context, attrs);
// Set Angle to 0 initially or whatever you want
arcAngle = 0;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(4);
mPaint.setColor(Color.WHITE);
mRect = new RectF(2, 2, 78, 78);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(mRect, 90, arcAngle, false, mPaint);
}
public float getArcAngle() {
return arcAngle;
}
public void setArcAngle(float arcAngle) {
this.arcAngle = arcAngle;
}
}
And here is how your animation Class looks like
public class ArcAngleAnimation extends Animation {
private ArcView arcView;
private float oldAngle;
private float newAngle;
public ArcAngleAnimation(ArcView arcView, int newAngle) {
this.oldAngle = arcView.getArcAngle();
this.newAngle = newAngle;
this.arcView = arcView;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation transformation) {
float angle = oldAngle + ((newAngle - oldAngle) * interpolatedTime);
arcView.setArcAngle(angle);
arcView.requestLayout();
}
public void setNewAngle(int newAngle){
this.newAngle = newAngle;
}
public void setOldAngle(float oldAngle) {
this.oldAngle = oldAngle;
}
}
Now all you need to do is apply animation and run it in your activity or fragment
ArcView view = (ArcView) findViewById(R.id.arc_view);
ArcAngleAnimation arcAnimation;
arcAnimation = new ArcAngleAnimation(view, 30);
arcAnimation.setFillAfter(true);
arcAnimation.setDuration(200);
view.startAnimation(arcAnimation);
I read a tutorial online about drawing a Circle (1st part of tutorial):
Introduction to 2D drawing in Android with example
I got it worked. Now I want to separate them into 2 classes:
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SimpleView(this));
}
}
SimpleView.java
public class SimpleView extends SurfaceView {
public SimpleView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
int radius;
radius = 100;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.GREEN);
canvas.drawPaint(paint);
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#CD5C5C"));
canvas.drawCircle(x / 2, y / 2, radius, paint);
}
}
However, I wasn't able to get them work: it never draws anything.
What did I do wrong here?
If you want to use a SurfaceView you can, all you need to do is to call setWillNotDraw(false) on the constructor so the class will look like this:
public class SimpleView extends SurfaceView {
public SimpleView(Context ctx) {
super(ctx);
setWillNotDraw(false); //notice this method call IMPORTANT
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
int radius;
radius = 100;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.GREEN);
canvas.drawPaint(paint);
// Use Color.parseColor to define HTML colors
paint.setColor(Color.parseColor("#CD5C5C"));
canvas.drawCircle(x / 2, y / 2, radius, paint);
}
}
Requirement is to:
Req 1 : Fetch images from url
R2: save them in cache
R3: make ImageView rounded not the image
So for R1 & R2 I found a library:
http://loopj.com/android-smart-image-view/
For R3 I've done a lot of R&D , & everything I found converts the image not the ImageView. This is what I've searched:
Mask ImageView with round corner background
How to make an ImageView with rounded corners?
https://github.com/vinc3m1/RoundedImageView
https://github.com/lopspower/CircularImageView
I know it's possible to use the ImageView bitmap & get the image rounded but with the specific library I want to use that isn't possible(maybe possible with very complex threading).
So please help me to get the ImageView rounded not the image.
so this is the minimalistic version:
class RoundImageView extends ImageView {
private static final int RADIUS = 32;
private Paint mPaint;
private Paint mSrcIn;
private RectF mRect;
public RoundImageView(Context context) {
super(context);
// setBackgroundColor(0xffffffff);
mSrcIn = new Paint();
mSrcIn.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRect = new RectF();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
int rtc = canvas.saveLayer(mRect, null, Canvas.ALL_SAVE_FLAG);
// draw DST
canvas.drawRoundRect(mRect, RADIUS, RADIUS, mPaint);
canvas.saveLayer(mRect, mSrcIn, Canvas.ALL_SAVE_FLAG);
// draw SRC
super.onDraw(canvas);
canvas.restoreToCount(rtc);
}
}
}
or use even shorter one when hardware acceleration is not used and you can use Canvas.clipPath:
class RoundImageViewClipped extends ImageView {
private static final int RADIUS = 32;
private RectF mRect;
private Path mClip;
public RoundImageViewClipped(Context context) {
super(context);
// setBackgroundColor(0xffffffff);
mRect = new RectF();
mClip = new Path();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
mClip.reset();
mClip.addRoundRect(mRect, RADIUS, RADIUS, Direction.CCW);
canvas.clipPath(mClip);
super.onDraw(canvas);
}
}
}
I'm pretty sure you can't "make the ImageView round," since all Views are actually rectangular, so what you're going to have to do is fake it.
Use a method like this to cut a circle from the image:
public Bitmap getRoundedBitmap(Bitmap scaleBitmapImage) {
int targetRadius = scaleBitmapImage.getWidth();
if(targetRadius > scaleBitmapImage.getHeight()) targetRadius = scaleBitmapImage.getHeight();
Bitmap targetBitmap = Bitmap.createBitmap(targetRadius, targetRadius, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addCircle(((float) scaleBitmapImage.getWidth() - 1) / 2, ((float) scaleBitmapImage.getHeight() - 1) / 2, (Math.min(((float) scaleBitmapImage.getWidth()), ((float) scaleBitmapImage.getHeight())) / 2), Path.Direction.CCW);
canvas.clipPath(path);
Bitmap sourceBitmap = scaleBitmapImage;
canvas.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight()), new Rect(0, 0, scaleBitmapImage.getWidth(), scaleBitmapImage.getHeight()), null);
return targetBitmap;
}
Since the clipped part is transparent, it will appear as if the actual View is a circle. Also make sure that the bounds of the View are squared (or that adjustViewBounds="true") else you may get visual distortions in terms of width or height.
Pretty sure that's as close to a "rounded View" as you can actually get.
How about the solution give by Romain Guy to use a custom Drawable. You're ImageView will not be round and your source image will be untouched.
class StreamDrawable extends Drawable {
private final float mCornerRadius;
private final RectF mRect = new RectF();
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;
StreamDrawable(Bitmap bitmap, float cornerRadius, int margin) {
mCornerRadius = cornerRadius;
mBitmapShader = new BitmapShader(bitmap,
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
mMargin = margin;
}
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin);
}
#Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
}
You can add rounded corners in a android view with the GradientDrawable.
So ,
GradientDrawable gd = new GradientDrawable();
gd.setColor(Color.TRANSPARENT);
gd.setCornerRadius(15f);
gd.setStroke(1f,Color.BLACK);
yourImageView.setBackground(gd);
SmartImageView extends from ImageView .. so you just have to extend from SmartImageView
Here is a working solution (based on pskink code & smartImageView lib )
Create a new Class
public class RoundedCornersSmartImageView extends SmartImageView{
private int RADIUS = 0;
private RectF mRect;
private Path mClip;
public RoundedCornersSmartImageView(Context context) {
super(context);
init();
}
public RoundedCornersSmartImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedCornersSmartImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
#Override
public void onDraw(Canvas canvas) {
Drawable dr = getDrawable();
if (dr != null) {
mRect.set(dr.getBounds());
getImageMatrix().mapRect(mRect);
mRect.offset(getPaddingLeft(), getPaddingTop());
mClip.reset();
mClip.addRoundRect(mRect, RADIUS, RADIUS, Path.Direction.CCW);
canvas.clipPath(mClip);
super.onDraw(canvas);
}
}
public void setRadius(int radius){
this.RADIUS = radius;
}
private void init(){
mRect = new RectF();
mClip = new Path();
}
}
USAGE
in your layout file your SmartimageView should look like this
<your.package.path.RoundedCornersSmartImageView
android:id="#+id/list_image"
android:layout_width="60dip"
android:layout_height="60dip"
android:src="#drawable/profile_anonyme_thumb"/>
..and init the view in your code this way
RoundedCornersSmartImageView thumb_image=(RoundedCornersSmartImageView) findViewById(R.id.list_image);
thumb_image.setRadius(4);
//SmartImageView methode
thumb_image.setImageUrl(bla.MY_THUMB_URL));
Edit your radius for a round image ..