How to Add a Shadow and a Border on Circular Imageview Android

How to add a shadow and a border on circular imageView android?

I modified the CircularImageView found here to achieve what you want.

To create a shadow around the border, I simply used these two lines:

this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);

You need setLayerType due to hardware acceleration on HoneyComb and up. It didn't work without it when I tried it.

Here is the full code:

import android.annotation.SuppressLint;
import android.content.Context;
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.util.AttributeSet;
import android.widget.ImageView;

public class CircularImageView extends ImageView
{
private int borderWidth = 4;
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);
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);
}
}

I hope it helps!

.

EDIT

I forked your CircularImageView and added support for selector overlays. I also improved drawing performance significantly...

https://github.com/Pkmmte/CircularImageView

How to add shadow around circular imageview

Here, I share my best practice to show a shadow effect to a circular image/resource with some details.

Sample Image

The above example image's icon is 56dp x 56dp and is cropped with a zoomed view so it may not look attractive but the results will show good on an actual device under the naked eye.

The above example is delivered by using:

  • Some amount of elevation, to let shadow.
  • Provide margin to the view almost double of elevation to fit the shadow.
  • Ensure the parent view provides the space almost double of elevation to fit the shadow.
  • Create and use an OutlineProvider to create the shadow.

Now here we begin with the code.

<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/margin_14dp"> // Point no. 3

<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/img"
android:layout_width="@dimen/margin_56dp"
android:layout_height="@dimen/margin_56dp"
android:layout_margin="@dimen/margin_14dp" // Point no. 2
android:elevation="@dimen/margin_8dp" // Point no. 1
android:src="@drawable/ic_bell" />
</FrameLayout>

Let's proceed to point no. 4, here is the OutlineProvider class for a Circular Outline.

import android.graphics.Outline;
import android.view.View;
import android.view.ViewOutlineProvider;

public class CircularOutlineProvider extends ViewOutlineProvider {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), (view.getWidth() / 2F));
}
}

We left to use the OutlineProvider in our Java/Kotlin class to do the magic at runtime.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
findViewById(R.id.img).setOutlineProvider(new CircularOutlineProvider());

End of Magic Session!

For more experience and enhance details, please read the official article.

Add Frame or Border to ImageView and Drop-Shadow

This can be done with proper padding and 9 patch image. See this link, may be it can help you.

ImageView in circular through XML

You can make a simple circle with white border and transparent content with shape.

// res/drawable/circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9"
android:useLevel="false" >
<solid android:color="@android:color/transparent" />

<stroke
android:width="10dp"
android:color="@android:color/white" />
</shape>

Then make a layerlist drawable and put it as background to your imageview.

// res/drawable/img.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

<item android:drawable="@drawable/circle"/>
<item android:drawable="@drawable/ic_launcher"/>

</layer-list>

and put it as background to your imageview.

   <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img"/>

You'll have something like that.

Sample Image

Android LinearLayout : Add border with shadow around a LinearLayout

Try this..

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#CABBBBBB"/>
<corners android:radius="2dp" />
</shape>
</item>

<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="@android:color/white"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>


Related Topics



Leave a reply



Submit