如何在圆形图像上添加阴影和边框androidView?

我用这个问题创build了一个CircularImageView: 在android中创build圆形图像视图

GitHub上下载项目

1)这是CircularImageView类:

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() ; Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); Bitmap roundBitmap = getCroppedBitmap(bitmap, getWidth()); 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(), Bitmap.Config.ARGB_8888); final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight()); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); paint.setColor(Color.parseColor("#BAB399")); Canvas c = new Canvas(output); c.drawARGB(0, 0, 0, 0); c.drawCircle(sbmp.getWidth() / 2+0.7f, sbmp.getHeight() / 2+0.7f, sbmp.getWidth() / 2+0.1f, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); c.drawBitmap(sbmp, rect, rect, paint); return output; } } 

2)我在这样的布局中使用:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#cccccc" android:gravity="center" android:orientation="vertical" android:padding="10dp" > <com.mikhaellopez.circularimageview.CircularImageView android:id="@+id/imageViewCircular" android:layout_width="@dimen/image_view_size" android:layout_height="@dimen/image_view_size" android:layout_gravity="center" android:background="@drawable/border" android:src="@drawable/image" /> </LinearLayout> 

3)当前结果图片:

当前结果

如何更改此代码以在我的imageView周围有阴影和圆形边框?

客观结果:

物化结果


编辑10/15/2015:

您可以使用或下载我的GitHub库 CircularImageView所有修补程序通过使用gradle依赖

 compile 'com.mikhaellopez:circularimageview:2.0.1' 

我修改了在这里find的CircularImageView来实现你想要的。

为了在边界周围创造阴影,我简单地使用了这两行:

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

由于HoneyComb和硬件加速,你需要setLayerType 。 没有它,当我尝试它时,它不工作。

以下是完整的代码:

 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); } } 

我希望它有帮助!

编辑

我分叉你的CircularImageView并添加了对select器叠加的支持。 我也大大提高了绘图性能…

https://github.com/Pkmmte/CircularImageView

通过将imageview作为一个圆圈添加边框,我做了一件简单的事情,我用这个类来使我的图像成为一个圆圈

  package com.fidenz.fexceller.fexceller; /** * Created by Chathu Hettiarachchi on 5/18/2015. */ import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.Drawable; public class RoundedImg extends Drawable { private final Bitmap mBitmap; private final Paint mPaint; private final RectF mRectF; private final int mBitmapWidth; private final int mBitmapHeight; public RoundedImg(Bitmap bitmap) { mBitmap = bitmap; mRectF = new RectF(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(shader); mBitmapWidth = mBitmap.getWidth(); mBitmapHeight = mBitmap.getHeight(); } @Override public void draw(Canvas canvas) { canvas.drawOval(mRectF, mPaint); } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mRectF.set(bounds); } @Override public void setAlpha(int alpha) { if (mPaint.getAlpha() != alpha) { mPaint.setAlpha(alpha); invalidateSelf(); } } @Override public void setColorFilter(ColorFilter cf) { mPaint.setColorFilter(cf); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } @Override public int getIntrinsicWidth() { return mBitmapWidth; } @Override public int getIntrinsicHeight() { return mBitmapHeight; } public void setAntiAlias(boolean aa) { mPaint.setAntiAlias(aa); invalidateSelf(); } @Override public void setFilterBitmap(boolean filter) { mPaint.setFilterBitmap(filter); invalidateSelf(); } @Override public void setDither(boolean dither) { mPaint.setDither(dither); invalidateSelf(); } public Bitmap getBitmap() { return mBitmap; } } 

并通过使用Oncreate我有调用图像设置它,

 profilePic = (ImageView)findViewById(R.id.img_home_profile_pic); Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.no_image); roundedImage = new RoundedImg(bm); profilePic.setImageDrawable(roundedImage); 

添加一个边框我创build了一个这样的圆形XML,

 <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <gradient android:startColor="@color/ring_color" android:endColor="@color/ring_color" android:angle="270"/> </shape> 

然后使用布局,我添加了一个与imageview里面的一个relativeLayout,通过使用填充和背景drawable与wrapcontent我设置我这样的相对布局

 <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/lay_rel_img" android:layout_gravity="center" android:padding="5dp" android:background="@drawable/circle"> <ImageView android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center" android:id="@+id/img_home_profile_pic" android:src="@drawable/no_image" android:layout_centerHorizontal="true"/> </RelativeLayout> 

现在这个表演就是这样,我不知道要补充那个影子,对不起

在这里输入图像描述

  1. 添加canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, paint);canvas.drawBitmap(roundBitmap, 0, 0, null);
  2. 更改c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2, paint);c.drawCircle(sbmp.getWidth() / 2, sbmp.getHeight() / 2, sbmp.getWidth() / 2 - "the border with you prefer", paint);

希望它有帮助。

也许这里更好的解决scheme。

创build一个自定义drawable,并使用它来定义你的ImageView的背景属性。 您可以使用LayeredDrawable,根据需要为组件创build许多不同的组件。

检出这个答案,它创build了一个自定义的Rectangle(但是与椭圆\ Circle完全相同): 如何在列表视图中创buildGoogle + cards UI?

在绘制实际图像之前,只需使用更多宽度和高度的drawCircle()方法即可。 根据你的意愿增加新方法调用的宽度和高度,并在paint上设置一些你想要的颜色

我发现了一个图书馆,正是你想要的,为我工作得很好。 一探究竟。 https://android-arsenal.com/details/1/932