在实际开发中我们经常会对图片进行圆角处理,这里做一个小总结,文章结尾还有一个不到100行实现的,支持圆形,圆角和TransitionDrawable的ImageView
。
实现这种效果有两种方式:
public Bitmap getRoundRectBitmap(Bitmap bitmap, int radius) { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); int bmWidth = bitmap.getWidth(); int bmHeight = bitmap.getHeight(); final RectF rectF = new RectF(0, 0, width, height); Canvas canvas = new Canvas(bitmap); paint.setXfermode(null); canvas.drawRoundRect(rectF, radius, radius, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rectF, paint); return bitmap; }
@Override protected void onDraw(Canvas canvas) { int saveCount = canvas.getSaveCount(); canvas.save(); super.onDraw(canvas); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawRoundRect(rectF, radius, radius, mPaint); canvas.restoreToCount(saveCount); }
圆形
圆角矩形
ShapedImageViewTransitionDrawable
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:test="http://schemas.android.com/apk/res/com.example.shapeimage" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" > <com.example.shapeimage.ShapedImageView android:id="@+id/image1" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true" android:src="@drawable/an" test:shape_mode="circle" /> <com.example.shapeimage.ShapedImageView android:id="@+id/image1" android:layout_width="200dp" android:layout_height="200dp" android:layout_marginTop="20dp" android:layout_centerInParent="true" test:round_radius="20dp" android:src="@drawable/an" test:shape_mode="round_rect" /> </LinearLayout>
一个属性资源文件attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ShapedImageView"> <attr name="shape_mode" format="enum"> <enum name="round_rect" value="1" /> <enum name="circle" value="2" /> </attr> <attr name="round_radius" format="dimension" /> </declare-styleable> </resources>
最重要的就是ShapedImageView.java这个类
import java.util.Arrays; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuff; import android.graphics.drawable.shapes.RoundRectShape; import android.graphics.drawable.shapes.Shape; import android.os.Build; import android.util.AttributeSet; import android.widget.ImageView; public class ShapedImageView extends ImageView { private static final int SHAPE_MODE_ROUND_RECT = 1; private static final int SHAPE_MODE_CIRCLE = 2; private int mShapeMode = 0; private float mRadius = 0; private Shape mShape; private Paint mPaint; public ShapedImageView(Context context) { super(context); init(null); } public ShapedImageView(Context context, AttributeSet attrs) { super(context, attrs); init(attrs); } public ShapedImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { setLayerType(LAYER_TYPE_HARDWARE, null); } if (attrs != null) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ShapedImageView); mShapeMode = a.getInt(R.styleable.ShapedImageView_shape_mode, 0); mRadius = a.getDimension(R.styleable.ShapedImageView_round_radius, 0); a.recycle(); } mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setFilterBitmap(true); mPaint.setColor(Color.BLACK); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (changed) { switch (mShapeMode) { case SHAPE_MODE_ROUND_RECT: break; case SHAPE_MODE_CIRCLE: int min = Math.min(getWidth(), getHeight()); mRadius = (float) min / 2; break; } if (mShape == null) { float[] radius = new float[8]; Arrays.fill(radius, mRadius); mShape = new RoundRectShape(radius, null, null); } mShape.resize(getWidth(), getHeight()); } } @Override protected void onDraw(Canvas canvas) { int saveCount = canvas.getSaveCount(); canvas.save(); super.onDraw(canvas); switch (mShapeMode) { case SHAPE_MODE_ROUND_RECT: case SHAPE_MODE_CIRCLE: if (mShape != null) { mShape.draw(canvas, mPaint); } break; } canvas.restoreToCount(saveCount); } }
如果图片展示出来不全或者变形,可以参考<ImageView的Scaletype的属性>这篇文章去根据自己的需要设置响应的值(推荐使用scaleType="centerCrop")。
好了,基本到这里就实现我们要的效果了,最后放上源码下载地址:
首先是github上面的项目源码地址:点击跳转到项目源码地址
然后是Eclipse工程格式的demo下载地址: 点击下载demo