Rounded imageview issue android - android

I am trying to get rounded border for an imageview. Here is the code for it:
http://stackoverflow.com/a/3292810/4224275
My problem is for a normal imageview declared as follows, how do I use the class object to make the image rounded. Here is my code which didn't work.
private ImageView imageView;
imageView = (ImageView) findViewById(R.id.imageView1);
imageView.buildDrawingCache();
Bitmap bmap = imageView.getDrawingCache();
ImageHelper imh = new ImageHelper();
imh.getRoundedCornerBitmap(bmap, 10);
It doesn't work for me. I don't know what to do.
Here is the logcat output:

Take a look in my example:
public class RoundedNetworkImageView extends NetworkImageView {
public RoundedNetworkImageView(Context context) {
super(context);
}
public RoundedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable _drawable = getDrawable();
if (_drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap _bitmap = ((BitmapDrawable)_drawable)
.getBitmap().copy(Bitmap.Config.ARGB_8888, true);
canvas.drawBitmap(getCroppedBitmap(_bitmap, (int) (getWidth() / 1.2f)), 0,0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bitmap, int radius) {
Bitmap _newBitmap;
if(bitmap.getWidth() != radius || bitmap.getHeight() != radius) {
_newBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);
}
else{
_newBitmap = bitmap;
}
Bitmap _outBitmap = Bitmap.createBitmap(_newBitmap.getWidth(),
_newBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas _canvas = new Canvas(_outBitmap);
Paint _paint = new Paint();
Rect _rect = new Rect(0, 0, _newBitmap.getWidth(), _newBitmap.getHeight());
_paint.setAntiAlias(true);
_paint.setFilterBitmap(true);
_paint.setDither(true);
_canvas.drawARGB(0, 0, 0, 0);
_paint.setColor(Color.parseColor("#BAB399"));
_canvas.drawCircle(_newBitmap.getWidth() / 2, _newBitmap.getHeight() / 2,
_newBitmap.getWidth() / 2.5f, _paint);
_paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
_canvas.drawBitmap(_newBitmap, _rect, _rect, _paint);
return _outBitmap;
}
}
In the xml:
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/imgShot_shotDetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
In the activity:
NetworkImageView imgShot = headerView.findViewById(R.id.imgShot_shotDetail);
imgShot.setImageUrl(url, AppControllerImage.getInstance().getImageLoader());
imgShot.setDefaultImageResId(R.drawable.notfound);
imgShot.setErrorImageResId(R.drawable.notfound);
In this case, I've used NetworkImageView from Volley library, but you can use a ImageView instead. You just have to adapt the code.

Related

How to make color filter round on an Android ImageView?

I'm using a custom class (extension of ImageView) to have an XML round image view. The problem is when I call .setColorFilter() it doesn't adhere to the same circular/round bounds.
How can I make the color filter only affect the image and not the entire rectangle of the view?
Here is my custom class for reference:
public class RoundedCornerImageFilterView extends ImageFilterView {
public RoundedCornerImageFilterView(Context context) {
super(context);
}
public RoundedCornerImageFilterView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedCornerImageFilterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setImageFilter(int color) {
this.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth();
int h = getHeight();
Bitmap roundedCornerBitmap = getRoundedCornerBitmap(bitmap, h, w);
canvas.drawBitmap(roundedCornerBitmap, 0, 0, null);
}
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int height, int width) {
Bitmap sbmp;
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0,
(width), (height));
final RectF rectF = new RectF(rect);
final float roundPx = 28;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
My xml implementation:
<MY_PATH.RoundedCornerImageFilterView
android:id="#+id/MY_IMAGE_VIEW"
android:layout_width="match_parent"
android:layout_height="150dp"
/>
Me trying to set the color filter:
MY_IMAGE_VIEW.setColorFilter(Color.parseColor(color), PorterDuff.Mode.OVERLAY)
Before the filter (looking like it's supposed to):
After setting the filter (you can see the square edges now):
Although the image (bitmap) has been given rounded corners, the canvas that it is written to has not. Since the color filter is being applied to the canvas, the tint spills out into the corners.
I suggest that you apply a rounded rectangle to a path then clip the path to the canvas. Something like this:
public class RoundedImageView extends AppCompatImageView {
private final Path mPath = new Path();
public RoundedImageView(Context context) {
super(context);
init();
}
public RoundedImageView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundedImageView(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setColorFilter(Color.RED, PorterDuff.Mode.OVERLAY);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mPath.reset();
mPath.addRoundRect(new RectF(0, 0, w, h), 128, 128, Path.Direction.CW);
}
#Override
public void draw(Canvas canvas) {
canvas.save();
canvas.clipPath(mPath);
super.draw(canvas);
canvas.restore();
}
}
I am using ImageView here, but the concept remains the same.
If you do this type of clipping, then rounding the bitmap becomes superfluous since it will also be clipped to the path.

Android Circular Network Image View showing different sizes

Here is the code for implementing CircularNetworkImageView. I got what I wanted but the problem here is that the sizes of the circle images are not fixed. Some are either small or large. And depending on the size, the images are somewhat like jumping on different positions within the view layout. I have already set a fixed width and height on xml but the problem is still there. Please help me with this.
public class CircularNetworkImageView extends NetworkImageView {
Context mContext;
public CircularNetworkImageView(Context context) {
super(context);
mContext = context;
}
public CircularNetworkImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
mContext = context;
}
public CircularNetworkImageView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
mContext = context;
}
#Override
public void setImageBitmap(Bitmap bm) {
if(bm==null) return;
setImageDrawable(new BitmapDrawable(mContext.getResources(),
getCircularBitmap(bm)));
}
/**
* Creates a circular bitmap and uses whichever dimension is smaller to determine the width
* <br/>Also constrains the circle to the leftmost part of the image
*
* #param bitmap
* #return bitmap
*/
public Bitmap getCircularBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
int width = bitmap.getWidth();
if(bitmap.getWidth()>bitmap.getHeight())
width = bitmap.getHeight();
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, width, width);
final RectF rectF = new RectF(rect);
final float roundPx = width / 2;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
I got this code on this link here: CircularNetworkImageView.
I was also experiencing that issue before and luckily I found this one. Try this code instead:
public class CircleImageView extends NetworkImageView {
private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 2;
private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private static final boolean DEFAULT_BORDER_OVERLAY = false;
private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
private final Paint mBorderPaint = new Paint();
private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private Bitmap mBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;
private float mDrawableRadius;
private float mBorderRadius;
private ColorFilter mColorFilter;
private boolean mReady;
private boolean mSetupPending;
private boolean mBorderOverlay;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
a.recycle();
init();
}
private void init() {
super.setScaleType(SCALE_TYPE);
mReady = true;
if (mSetupPending) {
setup();
mSetupPending = false;
}
}
#Override
public ScaleType getScaleType() {
return SCALE_TYPE;
}
#Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}
#Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}
#Override
protected void onDraw(Canvas canvas) {
if (getDrawable() == null) {
return;
}
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
if (mBorderWidth != 0) {
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setup();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public void setBorderColorResource(#ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
public boolean isBorderOverlay() {
return mBorderOverlay;
}
public void setBorderOverlay(boolean borderOverlay) {
if (borderOverlay == mBorderOverlay) {
return;
}
mBorderOverlay = borderOverlay;
setup();
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mBitmap = bm;
setup();
}
#Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
setup();
}
#Override
public void setImageResource(#DrawableRes int resId) {
super.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
#Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
#Override
public void setColorFilter(ColorFilter cf) {
if (cf == mColorFilter) {
return;
}
mColorFilter = cf;
mBitmapPaint.setColorFilter(mColorFilter);
invalidate();
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
return null;
}
}
private void setup() {
if (!mReady) {
mSetupPending = true;
return;
}
if (mBitmap == null) {
return;
}
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
mBorderRect.set(0, 0, getWidth(), getHeight());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
mDrawableRect.set(mBorderRect);
if (!mBorderOverlay) {
mDrawableRect.inset(mBorderWidth, mBorderWidth);
}
mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
updateShaderMatrix();
invalidate();
}
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}
use this one :
public class CircularImageView extends ImageView{
public CircularImageView(Context context) {
super(context);
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
if(b != null) {
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getRoundBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
}
public static Bitmap getRoundBitmap(Bitmap bmp, int radius) {
Bitmap sBmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sBmp= bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sBmp, rect, rect, paint);
return output;
}
}
The original "CircularNetworkImageView.java" class is not well organized to use in recyclerview or listview. It calculates different sizes for each image. I have edited the "getCircularBitmap" method of original class, in order to get same-sized and same-positioned circular imageviews in recyclerview, listview.
Here is the edited class link(GitHub)
You can use Picasso library with Circular imageview to show image from url
add this 2 file to gradle
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'de.hdodenhof:circleimageview:2.1.0'
then add this line to the xml
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/profile_image"
android:layout_width="96dp"
android:layout_height="96dp"
android:src="#drawable/profile"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"/>
Finally add these lines in onCreate
CircleImageView image = (CircleImageView) findViewById(R.id.profile_image);
Picasso.with(this).load("image url here")).noFade().into(image);
that's it.. now you can able to see image from online inside circular image view
I would usually set an image with circle cut out as a foreground. I make the remaining parts of the image the same color as background of the view it is on. Requires no additional code.

Using picasso library with a circle image view

I am looking at using the Picasso library to download an image from URL and pass this into circle image view, but since picasso requires that you pass in an actual imageView I have come to a standstill on how to do it
I am using the picasso library from here http://square.github.io/picasso/
and the circle image view class from here https://github.com/hdodenhof/CircleImageView
Here is the start of my code to get the image
private void getData() {
userName.setText(prefs.getString("userName",""));
jobTitle.setText(prefs.getString("profile",""));
userLocation.setText(prefs.getString("location",""));
// ??????
// Picasso.with(context).load(image link here).into(imageview here);
//CircleImageView img = new CircleImageView(this);
//img.setImageResource();
//img.setImageBitmap();
//img.setImageDrawable();
//img.setImageURI();
}
Edit:
here is the xml for the circleImageView
<michael.CircleImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/shadow"
android:layout_gravity="center"
android:layout_marginTop="16dp"
app:border_width="2dp"
app:border_color="#274978"
android:id="#+id/circleImageView"
I don't think you require CircleImageView library
You can implement Circular Transformation check the below gist
https://gist.github.com/julianshen/5829333
then
Picasso.with(activity).load(image link here)
.transform(new CircleTransform()).into(ImageView);
Use This
Activity Class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String imageUrl = "https://www.baby-connect.com/images/baby2.gif";
CircleImageView imageView = (CircleImageView) findViewById(R.id.image);
Picasso.with(getApplicationContext()).load(imageUrl)
.placeholder(R.drawable.images).error(R.drawable.ic_launcher)
.into(imageView);
}
}
Layout File
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/image"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_centerInParent="true"
android:src="#drawable/images"
app:border_color="#ffffff"
app:border_width="2dp" />
This is Working fine.
Use this code to create Circular Imageview ....
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable)drawable).getBitmap() ;
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0,0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if(bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(),
sbmp.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f,
sbmp.getWidth() / 2+0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
Take the ID of CircleImageView first :
CircleImageView mCircleImageView = (CircleImageView)findViewById(R.id.circleImageView);
And pass the ID to Picasso library :
Picasso.with(mContext).load(Uri.parse(link)).placeholder(drawable).into(mCircleImageView);
This worked for me.
I have created a target class that uses native Android's RoundedBitmapDrawable class to make image round (removes the need to add a circle transform class to code), see solution below:
public class RoundedImageBitmapTarget implements Target {
private final Context context;
private final ImageView view;
public RoundedImageBitmapTarget(Context context, ImageView view) {
this.context = context;
this.view = view;
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
setBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
setBitmap(((BitmapDrawable) errorDrawable).getBitmap());
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
setBitmap(((BitmapDrawable) placeHolderDrawable).getBitmap());
}
public void setBitmap(Bitmap bitmap) {
view.setImageDrawable(getRoundBitmap(context, bitmap));
}
public static RoundedBitmapDrawable getRoundBitmap(Context context, Bitmap bitmap) {
Resources res = context.getResources();
RoundedBitmapDrawable round = RoundedBitmapDrawableFactory.create(res, bitmap);
round.setCircular(true);
round.setTargetDensity(context.getResources().getDisplayMetrics());
return round;
}
public static void load(Context context, ImageView view, String url, int size, #DrawableRes int placeholder) {
RoundedImageBitmapTarget target;
Picasso.with(context).load(url)
.resize(0, size)
.placeholder(placeholder)
.error(placeholder)
.into(target = new RoundedImageBitmapTarget(context, view));
view.setTag(target);
}
}

How to create a rounded layout containing Imageview and a textview?

I have to create a framelayout which contains an ImageView and a TextView. How can I create a rounded layout so that they are shown as in the image. I tried adding round shape to the background of layout but it is not working.
I have one class that does the same work, check this one for your reference add this class inside the package and use this
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
if (b == null) {
return;
}
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
if(bitmap ==null)
{
return;
}
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp,
(int) (bmp.getWidth() / factor),
(int) (bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f,
radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
and use this type of XML for design
<com.packagename.RoundedImageView
android:id="#+id/odd_bubble"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_alignParentLeft="true"
android:layout_margin="5dip"
android:src="#drawable/index"
/>
You can use the ArcLibrary to achieve something like this:
<com.stelladk.arclib.ArcLayout
android:layout_width="200dp"
android:layout_height="200dp"
app:ArcType="inner"
app:ArcRadius="100dp"
android:background="#drawable/scenery">
<TextView
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="Change"
android:background="#color/semiwhite"
android:gravity="center"
android:layout_gravity="bottom"/>
</com.stelladk.arclib.ArcLayout>
Create a custom view and inside custom view's onDraw use canvas.drawText() to place the text. Now create a new class extending FrameLayout or RelativeLayout and use the above custom view class and RoundedImageView class as inner classes. Now inflate the 2 views inside the parent class. You can now get the rounded image as well as text below it.
FYI : You have to pass appropriate params to the drawText() method so that it is aligned in the required position

Irregular shaped buttons on the UI of an application.Android

I am in the process of creating an app which requires irregular shaped buttons. I know that i can use image buttons and have the irregular shapes set as the images but no matter what is the shape of the image, it always occupies a rectangular area on the screen.
Is it possible to have the button occupy the exact shape of the image alone?
Do i need to create a custom control or layout for doing this or is there any other valid approach?
If i need to create a custom layout then how do i ensure that the space enclosed by all the buttons that i have placed on the layout is always circular or elliptic?
You have to override onDraw method in any view you need to shape, see this code to round ImageView
public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
super(context);
init(context, null, 0);
}
public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
#SuppressLint("DrawAllocation") #Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = null;
int w = getWidth(), h = getHeight();
if (drawable instanceof BitmapDrawable) {
b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
if (drawable instanceof LayerDrawable) {
b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
((LayerDrawable) drawable).setBounds(0, 0, w, h);
((LayerDrawable) drawable).draw( new Canvas(b));
}
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f,
sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}

Categories

Resources