I want to place imageview in circular motion in xml - android

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.24">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/background_tree"
/>
<AbsoluteLayout
android:id="#+id/llMapContainer"
android:layout_width="match_parent"
android:layout_height="390dp"
android:layout_x="0dp"
android:layout_y="44dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/imgLocation"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_x="48px"
android:layout_y="440px"
android:src="#drawable/character_icon" />
</AbsoluteLayout>
</RelativeLayout>
</LinearLayout>
I want to place ImageView in the circles of the tree in my xml file . I tried using coordinates but it changes its positions with different screen size .

Step 1:Create CircularimageView.class
public class CircularImageView extends ImageView {
private int borderWidth;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private BitmapShader shader;
public CircularImageView(Context context) {
super(context);
setup();
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
private void setup() {
// init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
setBorderColor(Color.WHITE);
paintBorder.setAntiAlias(true);
this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
this.setBorderWidth(2);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
private void loadBitmap() {
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if (bitmapDrawable != null)
image = bitmapDrawable.getBitmap();
}
#SuppressLint("DrawAllocation")
#Override
public void onDraw(Canvas canvas) {
// load the bitmap
loadBitmap();
// init shader
if (image != null) {
shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
int circleCenter = viewWidth / 2;
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
viewWidth = width - (borderWidth * 2);
viewHeight = height - (borderWidth * 2);
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = viewWidth;
}
return result;
}
private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = viewHeight;
}
return (result + 2);
}
}
Step2:In layout.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.24">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.packagename.CircularImageView
android:id="#+id/imgLocation"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_x="48px"
android:layout_y="440px"
android:src="#drawable/character_icon" />
</RelativeLayout>
</LinearLayout>

Related

Round shape image without other library

I need get image from external memory and place that image into round shape
And also save that image into sheredprefernce
I tried may way but I can't make it
I need it to done without any external library
For Rounded imageview without any library you can use the below class.
package com.sample;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* Custom Circular Image view.
*/
public class RoundImageview extends ImageView {
private int borderWidth = 0;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private Paint shaderPaint;
private BitmapShader shader;
private static int mBorderColor = android.R.color.white;
private Context context;
private boolean needToDrawOverlay = true;
private AttributeSet attrs;
public RoundImageview(final Context context) {
super(context);
this.context = context;
}
public RoundImageview(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.attrs = attrs;
init();
}
public RoundImageview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
this.attrs = attrs;
init();
}
/**
* To initialize the paint components.
*/
private void init() {
Resources res = context.getResources();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, 0, 0);
int backgroundColor = a.getColor(R.styleable.RoundImageView_bg_color,
res.getColor(android.R.color.darker_gray));
a.recycle();
paint = new Paint();
paint.setAntiAlias(true);
shaderPaint = new Paint();
shaderPaint.setAntiAlias(true);
shaderPaint.setColor(backgroundColor);
shaderPaint.setStyle(Paint.Style.FILL);
paintBorder = new Paint();
paintBorder.setColor(mBorderColor);
borderWidth = 2;
paintBorder.setAntiAlias(true);
}
#Override
public void onDraw(Canvas canvas) {
// load the bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if (bitmapDrawable != null) {
image = bitmapDrawable.getBitmap();
}
if (needToDrawOverlay) {
int circleCenter = viewWidth / 2;
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter
+ borderWidth - 4.0f, shaderPaint);
}
// init shader
if (image != null) {
shader = createBitmapShader(image, canvas);
paint.setShader(shader);
// calculate the center point.
int circleCenter = viewWidth / 2;
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter
+ borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth,
circleCenter - 4.0f, paint);
}
}
/**
* To create bitmap shader.
*
* #param image
* #param canvas
* #return BitmapShader object
*/
private BitmapShader createBitmapShader(Bitmap image, Canvas canvas) {
return new BitmapShader(Bitmap.createScaledBitmap(image, this.getWidth(), this.getHeight(),
false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
viewWidth = width;
viewHeight = height;
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = viewWidth;
}
return result;
}
private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = viewHeight;
}
return (result);
}
}
Create a attrs.xml in the values module of the res module
<!-- Round Image view -->
<declare-styleable name="RoundImageView">
<attr name="bg_color" format="color" />
<attr name="border_color" format="color" />
</declare-styleable>
Use it in your layout this way
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:roundImageview="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.sample.RoundImageview
android:id="#+id/imageButton"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:src="#drawable/image"
roundImageview:bg_color="#000000" />
</RelativeLayout>

Irregular shading in Graph

I tried to replicate a donut chart code that I found in the net. The code is as follows
public class DonutChart extends View{
private float radius;
SharedPreferences prefs;
Paint paint;
Paint shadowPaint;
int a,b,c;
Path myPath;
Path shadowPath;
RectF outterCircle;
RectF innerCircle;
RectF shadowRectF;
public DonutChart(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.DonutChart,
0, 0
);
try {
radius = a.getDimension(R.styleable.DonutChart_radius, 20.0f);
} finally {
a.recycle();
}
paint = new Paint();
paint.setDither(true);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setAntiAlias(true);
paint.setStrokeWidth(radius / 14.0f);
shadowPaint = new Paint();
shadowPaint.setColor(0xf0000000);
shadowPaint.setStyle(Paint.Style.STROKE);
shadowPaint.setAntiAlias(true);
shadowPaint.setStrokeWidth(6.0f);
shadowPaint.setMaskFilter(new BlurMaskFilter(4, BlurMaskFilter.Blur.SOLID));
myPath = new Path();
shadowPath = new Path();
outterCircle = new RectF();
innerCircle = new RectF();
shadowRectF = new RectF();
float adjust = (.019f*radius);
shadowRectF.set(adjust, adjust, radius*2-adjust, radius*2-adjust);
adjust = .038f * radius;
outterCircle.set(adjust, adjust, radius*2-adjust, radius*2-adjust);
adjust = .276f * radius;
innerCircle.set(adjust, adjust, radius * 2 - adjust, radius * 2 - adjust);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw shadow
paint.setShader(null);
float adjust = (.0095f*radius);
paint.setShadowLayer(8, adjust, -adjust, 0xaa000000);
drawDonut(canvas, paint, 0, 359.9f);
//Orange
setGradient(0xffEF6632,0xffEF6632);
drawDonut(canvas,paint, 0,b);
//Blue
setGradient(0xff00CCDA,0xff00CCDA);
drawDonut(canvas, paint, 60,a);
// blue
// setGradient(0xff4AB6C1,0xff2182AD);
// drawDonut(canvas, paint, 120, 60);
// Grey
setGradient(0xff557687,0xff557687);
drawDonut(canvas, paint, 180,c);
}
public void drawDonut(Canvas canvas, Paint paint, float start,float sweep){
myPath.reset();
myPath.arcTo(outterCircle, start, sweep, false);
myPath.arcTo(innerCircle, start+sweep, -sweep, false);
myPath.close();
canvas.drawPath(myPath, paint);
}
public void setGradient(int sColor, int eColor){
paint.setShader(new RadialGradient(radius, radius, radius - 5,
new int[]{sColor, eColor},
new float[]{.6f, .95f}, TileMode.CLAMP));
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int desiredWidth = (int) radius*2;
int desiredHeight = (int) radius*2;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//70dp exact
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
}else if (widthMode == MeasureSpec.AT_MOST) {
//wrap content
width = Math.min(desiredWidth, widthSize);
} else {
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(desiredHeight, heightSize);
} else {
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
public void getData(int x,int y){
invalidate();
a=((x*360)/10);
b=(y*360)/10;
c=((10-(x+y))*360)/10;
String s1,s2,s3;
s1=String.valueOf(a);
s2=String.valueOf(b);
s3=String.valueOf(c);
Toast.makeText(getContext(),"Inside Chart "+s1+" "+s2+" "+s3 +" "+String.valueOf(x),Toast.LENGTH_SHORT).show();
}
}
The problem is when I render the graph on my device it gives me a weird shadow like this:
or like this:
What is causing this and how to rectify it?
This is actually caused because only the value of the line length is changed whereas the starting point is the same so sometimes they tend to overlap.
This can be solved by changing the code as follows
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw shadow
paint.setShader(null);
float adjust = (.0095f*radius);
paint.setShadowLayer(8, adjust, -adjust, 0xaa000000);
drawDonut(canvas, paint, 0, 359.9f);
//Orange
setGradient(0xffEF6632,0xffEF6632);
drawDonut(canvas,paint, 0,b);
//Blue
setGradient(0xff00CCDA,0xff00CCDA);
drawDonut(canvas, paint, b,a);
// Grey
setGradient(0xff557687,0xff557687);
drawDonut(canvas, paint, a+b,c);
}

Circular imageview with downloading from url

I am downloading image from url with ion library.It is working like this:
holder.imageView=(ImageView)convertView.findViewById(R.id.image);
Ion.with(holder.imageView).load(image_url);
My imageView xml:
<ImageView
android:id="#+id/image"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="#drawable/defaultprofile"/>
I want to use this imageview as circular imageview.
I have found that question:How to Make an ImageView in Circular Shape?
But in that question they are using static image.I mean they don't download from url.How can I use circular image with downloading from url or what is the best library for me ?
Use Picasso. It is the best (for me) image downloading library which also handles caching. https://github.com/square/picasso You can also set a placeholder while the image is loading and you can do so much more than that.
For the circular ImageView you can use this library: https://github.com/hdodenhof/CircleImageView or one of the others Butani Vijay gave, but you can also use transformation specifically for Picasso: https://gist.github.com/julianshen/5829333
I'm using Picasso with this transformation method in my own apps.
You can use any one of below :
https://github.com/hdodenhof/CircleImageView
https://github.com/Pkmmte/CircularImageView
https://github.com/lopspower/CircularImageView
You need to create custome ImageView
Example :
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class CircularImageView extends ImageView {
private int borderWidth;
private int canvasSize;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
public CircularImageView(final Context context) {
this(context, null);
}
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.circularImageViewStyle);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
// load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);
if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
}
if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
addShadow();
}
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.requestLayout();
this.invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
public void addShadow() {
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
// load the bitmap
image = drawableToBitmap(getDrawable());
// init shader
if (image != null) {
canvasSize = canvas.getWidth();
if(canvas.getHeight()<canvasSize)
canvasSize = canvas.getHeight();
BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// The parent has determined an exact size for the child.
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
private int measureHeight(int measureSpecHeight) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
public Bitmap drawableToBitmap(Drawable drawable) {
if (drawable == null) {
return null;
} else if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
And use as below in your layout :
<com.yourpkg.CircularImageView
android:layout_width="64dp"
android:layout_height="64dp"
android:src="#drawable/image"
app:border="true"
app:border_color="#color/GrayLight"
app:border_width="4dp"
app:shadow="true" />

custom circular image view

I am trying to create the circular image view. After searching google I have tried something but its not working.
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
class WheelItemView extends ImageView {
private int _index;
private float _x;
private float _y;
private int _width;
private int _height;
private boolean _drawn;
private float _currentAngle;
private Paint paint;
private Paint paintBorder;
private int borderWidth;
private boolean _hasRotation = false;
private float _dx=0;
private float _dy=0;
private Bitmap image;
private int canvasSize;
public WheelItemView(Context context) {
this(context, null);
}
public WheelItemView(Context context, AttributeSet attrs) {
this(context, attrs, in.eaft.byoo.R.attr.circularImageViewStyle);
// this(context, attrs, 0);
}
public WheelItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
// load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs, in.eaft.byoo.R.styleable.CircularImageView, defStyle, 0);
if(attributes.getBoolean(in.eaft.byoo.R.styleable.CircularImageView_border, true)) {
int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics()
.density + 0.5f);
setBorderWidth(attributes.getDimensionPixelOffset(in.eaft.byoo.R.styleable.
CircularImageView_border_width, defaultBorderSize));
setBorderColor(attributes.getColor(in.eaft.byoo.R.styleable.CircularImageView_border_color,
Color.WHITE));
}
if(attributes.getBoolean(in.eaft.byoo.R.styleable.CircularImageView_shadow, true))
addShadow();
}
private void addShadow() {
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
private void setBorderColor(int color) {
if(paintBorder != null)
paintBorder.setColor(color);
this.invalidate();
}
private void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.requestLayout();
this.invalidate();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/*_width= measureWidth(widthMeasureSpec);
_height = measureHeight(heightMeasureSpec);*/
setMeasuredDimension(_width, _height);
}
private int measureHeight(int measureSpecHeight) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// The parent has determined an exact size for the child.
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
#Override
public void setImageBitmap(Bitmap src)
{
_width = src.getWidth();
_height = src.getHeight();
if(_hasRotation) {
calculateDistance();
}
super.setImageBitmap(src);
}
#Override
protected void onDraw(Canvas canvas)
{
//if(_hasRotation) {
/*Drawable d = getDrawable();
if(d!=null && d instanceof BitmapDrawable && ((BitmapDrawable)d).getBitmap()!=null) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
canvas.save();
canvas.translate(_dx, _dy);
canvas.rotate(_currentAngle+90, _width/2f, _height/2f);
// canvas.drawText(text, 0, 0, p);
canvas.drawBitmap(((BitmapDrawable)d).getBitmap(),0, 0, p);
canvas.restore();
return;
}*/
System.out.println("get drawable is null : " + (getDrawable() == null));
image = drawableToBitmap(getDrawable());
// init shader
if (image != null) {
canvasSize = canvas.getWidth();
if(canvas.getHeight()<canvasSize)
canvasSize = canvas.getHeight();
BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize,
canvasSize, false),
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
canvas.save();
// canvas.translate(_dx, _dy);
canvas.rotate(_currentAngle+90, _width/2f, _height/2f);
canvas.drawCircle(_width-_dx, _height-_dy/2,
borderWidth * 10, paintBorder);
canvas.drawCircle(_width-_dx, _height-_dy/2,
borderWidth * 10, paint);
/*canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth,
((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth,
((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);*/
canvas.restore();
// }
}
super.onDraw(canvas);
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable == null) {
return null;
} else if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(70,
70, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
private void calculateDistance()
{
_dx = (float) ((Math.sqrt(_width*_width + _height*_height)-_width)/2.0f);
_dy = (float) ((Math.sqrt(_width*_width + _height*_height)-_height)/2.0f);
}
public void setIndex(int index)
{
this._index = index;
}
public int getIndex()
{
return _index;
}
public void setCurrentAngle(float currentAngle)
{
this._currentAngle = currentAngle;
}
public float getCurrentAngle()
{
return _currentAngle;
}
public void setAxisX(float x)
{
this._x = x;
}
public float getAxisX()
{
return _x;
}
public void setAxisY(float y)
{
this._y = y;
}
public float getAxisY()
{
return _y;
}
public void setDrawn(boolean drawn)
{
this._drawn = drawn;
}
public boolean isDrawn()
{
return _drawn;
}
public void setItemWidth(int _width)
{
this._width = _width;
}
public float getItemWidth()
{
return _width;
}
public void setItemHeight(int _height)
{
this._height = _height;
}
public float getItemHeight()
{
return _height;
}
public int getDistanceX()
{
return (int)_dx;
}
public int getDistanceY()
{
return (int)_dy;
}
public void setRotatedItem(Boolean flag)
{
_hasRotation = flag;
if(_hasRotation && (_dx==0 || _dy ==0)) {
calculateDistance();
}
if(!_hasRotation) {
_dx = _dy = 0;
}
}
}
My images are not circular.Instead part of circle is being displayed behind the square image.
can anyone tell me what mistake I have done?
I think ur asking for this
jst create a shape in res>drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#a7a7a7" />
<stroke android:width="1dp" android:color="#818181" />
</shape>
and use this shape in ur imageview

how can i show a square image in a circle?

I'm trying to mimic something from the iPhone version of my app. I have a square image and I want to show it in a circle with a white border around it. like this
Is there a way I can do this?
You can achieve this effect, or something very close to it, using a custom Drawable class, containing a Paint object with a BitmapShader that renders the image as a texture. This is the code I'm using (slightly adapted from Romain's Guy post, which uses the same technique to draw images with rounded corners).
class CircularDrawable extends Drawable
{
private float mCircleRadius;
private final RectF mBackgroundRect = new RectF();
private final Paint mBackgroundPaint;
private final BitmapShader mBitmapShader;
private final Paint mPaint;
private final int mMargin;
CircularDrawable(Bitmap bitmap, int margin, int backgroundColor)
{
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setShader(mBitmapShader);
mMargin = margin;
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(backgroundColor);
}
#Override
protected void onBoundsChange(Rect bounds)
{
super.onBoundsChange(bounds);
mBackgroundRect.set(bounds);
mCircleRadius = Math.min(bounds.width() / 2 - mMargin, bounds.height() / 2 - mMargin);
}
#Override
public void draw(Canvas canvas)
{
canvas.drawRect(mBackgroundRect, mBackgroundPaint);
canvas.drawCircle(mBackgroundRect.width() / 2, mBackgroundRect.height() / 2, mCircleRadius, mPaint);
}
#Override
public int getOpacity()
{
return PixelFormat.TRANSLUCENT;
}
#Override
public void setAlpha(int alpha)
{
mPaint.setAlpha(alpha);
mBackgroundPaint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter cf)
{
mPaint.setColorFilter(cf);
mBackgroundPaint.setColorFilter(cf);
}
}
Having the bitmap you want to draw, just build a CircularDrawable from it with
new CircularDrawable(bitmap, margin, Color.WHITE);
Try this.
public class CircularImageView extends ImageView {
private int borderWidth;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private BitmapShader shader;
public CircularImageView(final Context context) {
this(context, null);
}
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.circularImageViewStyle);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
// load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs,
R.styleable.CircularImageView, defStyle, 0);
if (attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
setBorderWidth(attributes.getColor(
R.styleable.CircularImageView_border_width, 4));
setBorderColor(attributes.getInt(
R.styleable.CircularImageView_border_color, Color.WHITE));
}
if (attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
addShadow();
}
public void setBorderWidth(int borderWidth) {
this.borderWidth = borderWidth;
this.invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
public void addShadow() {
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
#SuppressLint("DrawAllocation")
#Override
public void onDraw(Canvas canvas) {
// load the bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if (bitmapDrawable != null)
image = bitmapDrawable.getBitmap();
// init shader
if (image != null) {
shader = new BitmapShader(Bitmap.createScaledBitmap(image,
canvas.getWidth(), canvas.getHeight(), false),
Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
int circleCenter = viewWidth / 2;
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
canvas.drawCircle(circleCenter + borderWidth, circleCenter
+ borderWidth, circleCenter + borderWidth - 4.0f,
paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter
+ borderWidth, circleCenter - 4.0f, paint);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
viewWidth = width - (borderWidth * 2);
viewHeight = height - (borderWidth * 2);
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = viewWidth;
}
return result;
}
private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = viewHeight;
}
return (result + 2);
}
}
I'd make a custom view and just draw what you want to the canvas- draw the border, then the white circle, then the image.It's a couple of easy canvas calls. If you need to clip the image to a circular area, just set a clipping Region before doing the image draw.

Categories

Resources