所有方式均继承了ImageView
圆形图片实现一:BitmapShader
package com.open.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* 1.BitmapShader
*
* @author Administrator
*
*/
public class CircularImageView extends ImageView {
private BitmapShader mBitmapShader;
private Paint mBitmapPaint = new Paint();
private RectF mRoundRect=new RectF();
public CircularImageView(Context context) {
super(context);
initObjectAttribute();
}
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initObjectAttribute();
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
createBitmapShader();
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
// createBitmapShader();
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
createBitmapShader();
}
private void initObjectAttribute()
{
mBitmapPaint.setAntiAlias(true);
// if(getScaleType() != ScaleType.CENTER_CROP)
// {
// setScaleType(ScaleType.CENTER_CROP);
// }
}
private void createBitmapShader()
{
mBitmapShader = null;
Drawable mDrawable = getDrawable();
if (mDrawable == null)
{
return;
}
if(mDrawable instanceof BitmapDrawable)
{
BitmapDrawable bd = (BitmapDrawable) mDrawable;
Bitmap bitmap = bd.getBitmap();
mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
}
else //if Drawable instanceof NinePathDrawable ,the code below is bad , because a view reference two bitmap ( one in NinePath , other is here)
{
int w = mDrawable.getIntrinsicWidth();
int h = mDrawable.getIntrinsicHeight();
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
mDrawable.setBounds(0, 0, w, h);
mDrawable.draw(canvas);
mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mRoundRect.set(0,0,getMeasuredWidth(),getMeasuredHeight());
}
@Override
protected void onDraw(Canvas canvas) {
Drawable mDrawable = getDrawable();
if (null == mDrawable || null == mBitmapShader)
{
return;
}
Matrix mDrawMatrix= getImageMatrix();
if(null == mDrawMatrix)
{
mDrawMatrix =new Matrix();
}
mBitmapShader.setLocalMatrix(mDrawMatrix);
mBitmapPaint.setShader(mBitmapShader);
canvas.drawCircle(getWidth()/2, getHeight()/2, Math.min(getWidth()/2, getHeight()/2), mBitmapPaint);
}
}
圆形图片实现二:Path
package com.open.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* 2.Path
*
* @author Administrator
*
*/
public class CircularImageView2 extends ImageView {
private RectF mRoundRect=new RectF();
private Path mPath = new Path();
private PaintFlagsDrawFilter pfd=new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
public CircularImageView2(Context context) {
super(context);
initObjectAttribute();
}
public CircularImageView2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircularImageView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initObjectAttribute();
}
private void initObjectAttribute()
{
// if(getScaleType() != ScaleType.CENTER_CROP)
// {
// setScaleType(ScaleType.CENTER_CROP);
// }
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mRoundRect.set(0,0,getMeasuredWidth(),getMeasuredHeight());
}
@Override
protected void onDraw(Canvas canvas) {
Drawable mDrawable = getDrawable();
if (mDrawable == null)
{
return;
}
if (mDrawable.getIntrinsicWidth() == 0 || mDrawable.getIntrinsicHeight() == 0) {
return; // nothing to draw (empty bounds)
}
canvas.setDrawFilter(pfd);
canvas.save();
mPath.reset();
canvas.clipPath(mPath); // makes the clip empty
mPath.addCircle(getWidth()/2, getHeight()/2, Math.min(getWidth()/2, getHeight()/2), Path.Direction.CCW);
canvas.clipPath(mPath, Region.Op.REPLACE);
Matrix mDrawMatrix = getImageMatrix();
if (mDrawMatrix != null) {
canvas.concat(mDrawMatrix);
}
mDrawable.draw(canvas);
canvas.restore();
}
}
圆形图片实现三:setXfermode
package com.open.widget;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* 3.setXfermode
*
* @author Administrator
*
*/
public class CircularImageView3 extends ImageView {
private Paint paint = new Paint();
private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
private Bitmap maskBitmap=null;
private RectF mRoundRect=new RectF();
private int oldWidth;
private int oldHeight;
public CircularImageView3(Context context) {
super(context);
initObjectAttribute();
}
public CircularImageView3(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircularImageView3(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initObjectAttribute();
}
private void initObjectAttribute()
{
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了
// if(getScaleType() != ScaleType.CENTER_CROP)
// {
// setScaleType(ScaleType.CENTER_CROP);
// }
}
private void create_mask_bitmap(int w , int h)
{
if(null != maskBitmap && !maskBitmap.isRecycled())
{
maskBitmap.recycle();
maskBitmap=null;
}
maskBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas mCanvas = new Canvas(maskBitmap);
Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.TRANSPARENT);
mCanvas.drawCircle(w/2, h/2, Math.min(w/2, h/2), paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mRoundRect.set(0,0,getMeasuredWidth(),getMeasuredHeight());
if( oldWidth!=getMeasuredWidth() || oldHeight!=getMeasuredHeight() )
{
oldWidth = getMeasuredWidth() ;
oldHeight = getMeasuredHeight();
if(oldWidth > 0 && oldHeight >0)
{
create_mask_bitmap(oldWidth , oldHeight);
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Drawable mDrawable = getDrawable();
if (mDrawable == null)
{
return;
}
if (mDrawable.getIntrinsicWidth() == 0 || mDrawable.getIntrinsicHeight() == 0) {
return; // nothing to draw (empty bounds)
}
if(null == maskBitmap)
{
return;
}
int saveCount = canvas.getSaveCount();
canvas.save();
paint.setFilterBitmap(false);
paint.setXfermode(mXfermode);
canvas.drawBitmap(maskBitmap, null, mRoundRect, paint);
paint.setXfermode(null);
canvas.restoreToCount(saveCount);
}
}
这里主要是重用了ImageView,如果你想强制绘制的View为圆角或者圆形图片,把代码中注释的代码打开即可
private void initObjectAttribute()
{
mBitmapPaint.setAntiAlias(true);
// if(getScaleType() != ScaleType.CENTER_CROP)
// {
// setScaleType(ScaleType.CENTER_CROP);
// }
}
知识点不是很难,代码浅显易懂,当然最好去熟读一下ImageView的源码.
源码获取地址:
github : https://github.com/zz7zz7zz/android-image
csdn : http://download.csdn.net/detail/zz7zz7zz/9421399