Android 三种方式实现圆角ImageView

所有方式均继承了ImageView 



圆角图片实现一:BitmapShader


package com.open.widget;

import android.content.Context;
import android.content.res.TypedArray;
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.util.TypedValue;
import android.widget.ImageView;

import com.open.image.R;
/**
 * 1.BitmapShader
 * 
 * @author Administrator
 *
 */
public class RoundImageView extends ImageView {

	private final int DEFAULT_RADIUS=10;
	
	private BitmapShader mBitmapShader;
	private Paint mBitmapPaint = new Paint();
	private RectF mRoundRect=new RectF();
	private int x_radius;
	private int y_radius;
	
	public RoundImageView(Context context) {
		super(context);
		initObjectAttribute();
	}

	public RoundImageView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
		initObjectAttribute();
		
		final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);
		x_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_x_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));
		y_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_y_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));
		a.recycle();
		
		
	}

	private void initObjectAttribute()
	{
		mBitmapPaint.setAntiAlias(true);
//		if(getScaleType() != ScaleType.CENTER_CROP)
//		{
//			setScaleType(ScaleType.CENTER_CROP);
//		}
	}
	
	@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 createBitmapShader()
	{
		mBitmapShader = null;
		Drawable mDrawable = getDrawable();
		if (null == mDrawable)
		{
			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.drawRoundRect(mRoundRect, x_radius, y_radius,mBitmapPaint);
	}
}

Android 三种方式实现圆角ImageView_第1张图片




圆角图片实现二:Path


package com.open.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;

import com.open.image.R;
/**
 * 2.Path
 * 
 * @author Administrator
 *
 */
public class RoundImageView2 extends ImageView {

	private final int DEFAULT_RADIUS=10;
	
	private RectF mRoundRect=new RectF();
	private int x_radius;
	private int y_radius;
	private Path mPath = new Path();
	
	public RoundImageView2(Context context) {
		super(context);
		initObjectAttribute();
	}

	public RoundImageView2(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RoundImageView2(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
		initObjectAttribute();
		
		final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);
		x_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_x_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));
		y_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_y_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));
		a.recycle();
		
		
	}

	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.save();
        mPath.reset();
        canvas.clipPath(mPath); // makes the clip empty
        mPath.addRoundRect(mRoundRect, x_radius, y_radius, Path.Direction.CCW);
        canvas.clipPath(mPath, Region.Op.REPLACE);
        
        Matrix mDrawMatrix = getImageMatrix();
        if (mDrawMatrix != null) {
            canvas.concat(mDrawMatrix);
        }
        mDrawable.draw(canvas);
        
        canvas.restore();
	}
	
	
}


Android 三种方式实现圆角ImageView_第2张图片



圆角图片实现三:setXfermode


package com.open.widget;

import android.content.Context;
import android.content.res.TypedArray;
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.util.TypedValue;
import android.widget.ImageView;

import com.open.image.R;
/**
 * 3.setXfermode
 * 
 * @author Administrator
 *
 */
public class RoundImageView3 extends ImageView {
	
	private final int DEFAULT_RADIUS=10;

	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 x_radius;
	private int y_radius;
	private int oldWidth;
	private int oldHeight;
	
	public RoundImageView3(Context context) {
		super(context);
		initObjectAttribute();
	}

	public RoundImageView3(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RoundImageView3(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		
		initObjectAttribute();
		
		final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);
		x_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_x_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));
		y_radius=a.getDimensionPixelSize(R.styleable.RoundImageView_y_radius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,DEFAULT_RADIUS, getResources().getDisplayMetrics()));
		a.recycle();
	}

	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.drawRoundRect(new RectF(0, 0, w, h), x_radius, y_radius, 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);
	}
	
	
}

Android 三种方式实现圆角ImageView_第3张图片


这里主要是重用了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





你可能感兴趣的:(Android,基础教程)