Android神话级圆形图片控件RoundImageView

RoundImageView是在不修改ImageView原有绘图逻辑的情况下实现的圆形特性,完全兼容ImageView的所有特性。

无论你的图像控件布局是什么样的,图像内容是什么样的,RoundImageView不圆不是英雄!

无论你的图像控件ScaleType是什么样的,矩阵转换MATRIX是什么样的,RoundImageView不圆不是传说!

无论你的控件或图像经过何种变换,比如内边距偏移,缩放,居中等等,你会发现一个圆紧紧的跟随着你的控件或图片,不离不弃,这就是神话级的圆形控件RoundImageView!


RoundImageView的使用非常简单,无需任何额外依赖和xml属性配置,让哪些动辄就弄几个xml属性的都消失!

以下是几个常用属性设置接口:

1、setRoundMode:设置圆形模式。RoundImageView支持两种圆形模式:

(1)圆形视图:ROUND_VIEW, 使视图组件变圆;

(2)圆形图片:ROUND_DRAWABLE,使图片内容变圆。

2、setBorderColor:设置圆环颜色,默认为透明色;

3、setBorderWidth:设置圆环宽度,默认为0。如果圆环宽度小于等于0,圆环不会被绘制;

4、setFillColor:设置圆形区域填充背景色,默认为透明色。


源代码如下:


package com.example.roundimageview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.PorterDuff.Mode;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.ImageView;

public class RoundImageView extends ImageView {

	public enum RoundMode {
		ROUND_VIEW, ROUND_DRAWABLE
	}

	private static final int DEFAULT_BORDER_WIDTH = 0;
	private static final int DEFAULT_BORDER_COLOR = Color.TRANSPARENT;
	private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;

	private boolean roundDisable;
	private RoundMode roundMode = RoundMode.ROUND_DRAWABLE;
	private int borderColor = DEFAULT_BORDER_COLOR;
	private int borderWidth = DEFAULT_BORDER_WIDTH;
	private int fillColor = DEFAULT_FILL_COLOR;

	private Paint borderPaint;
	private Paint fillPaint;
	private Paint imagePaint;
	private Paint portPaint;

	private Rect bounds = new Rect();
	private float radius = 0;
	private float cx = 0;
	private float cy = 0;

	public RoundImageView(Context context) {
		super(context);
		initView();
	}

	public RoundImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView();
	}

	public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initView();
	}

	private void initView() {
		portPaint = new Paint();
		portPaint.setAntiAlias(true);

		borderPaint = new Paint();
		borderPaint.setAntiAlias(true);
		borderPaint.setColor(DEFAULT_BORDER_COLOR);
		borderPaint.setStrokeWidth(DEFAULT_BORDER_WIDTH);
		borderPaint.setStyle(Style.STROKE);

		fillPaint = new Paint();
		fillPaint.setAntiAlias(true);
		fillPaint.setColor(DEFAULT_FILL_COLOR);
		fillPaint.setStyle(Style.FILL);

		imagePaint = new Paint();
		imagePaint.setAntiAlias(true);
		imagePaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
	}

	public void setRoundMode(RoundMode roundMode) {
		if (roundMode == null) {
			throw new IllegalArgumentException("roundMode is null.");
		}

		if (this.roundMode != roundMode) {
			this.roundMode = roundMode;
			invalidate();
		}
	}

	public void setRoundDisable(boolean roundDisable) {
		if (this.roundDisable != roundDisable) {
			this.roundDisable = roundDisable;
			invalidate();
		}
	}

	public boolean isRoundDisable() {
		return roundDisable;
	}

	public void setBorderColor(int borderColor) {
		if (this.borderColor != borderColor) {
			this.borderColor = borderColor;
			borderPaint.setColor(borderColor);
			invalidate();
		}
	}

	public void setBorderWidth(int borderWidth) {
		if (this.borderWidth != borderWidth) {
			this.borderWidth = borderWidth;
			borderPaint.setStrokeWidth(borderWidth);
			invalidate();
		}
	}

	public void setFillColor(int fillColor) {
		if (this.fillColor != fillColor) {
			this.fillColor = fillColor;
			fillPaint.setColor(fillColor);
			invalidate();
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {

		if (roundDisable) {
			super.onDraw(canvas);
			return;
		}

		if (getDrawable() == null && roundMode == RoundMode.ROUND_DRAWABLE) {
			super.onDraw(canvas);
			return;
		}

		computeRoundBounds();
		drawCircle(canvas);
		drawImage(canvas);

	}

	private void drawImage(Canvas canvas) {
		Bitmap src = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
		super.onDraw(new Canvas(src));

		Bitmap port = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_4444);
		Canvas portCanvas = new Canvas(port);

		int saveCount = portCanvas.getSaveCount();
		portCanvas.save();
		adjustCanvas(portCanvas);
		portCanvas.drawCircle(cx, cy, radius, portPaint);
		portCanvas.restoreToCount(saveCount);

		portCanvas.drawBitmap(src, 0, 0, imagePaint);
		src.recycle();

		canvas.drawBitmap(port, 0, 0, null);
		port.recycle();

	}

	private void drawCircle(Canvas canvas) {
		int saveCount = canvas.getSaveCount();
		canvas.save();

		adjustCanvas(canvas);

		canvas.drawCircle(cx, cy, radius, fillPaint);
		if (borderWidth > 0) {
			canvas.drawCircle(cx, cy, radius - borderWidth / 2f, borderPaint);
		}

		canvas.restoreToCount(saveCount);

	}

	private void computeRoundBounds() {
		if (roundMode == RoundMode.ROUND_VIEW) {
			bounds.left = getPaddingLeft();
			bounds.top = getPaddingTop();
			bounds.right = getWidth() - getPaddingRight();
			bounds.bottom = getHeight() - getPaddingBottom();
		} else if (roundMode == RoundMode.ROUND_DRAWABLE) {
			getDrawable().copyBounds(bounds);
		} else {
			throw new RuntimeException("unknown round mode:" + roundMode);
		}

		radius = Math.min(bounds.width(), bounds.height()) / 2f;
		cx = bounds.left + bounds.width() / 2f;
		cy = bounds.top + bounds.height() / 2f;
	}

	private void adjustCanvas(Canvas canvas) {
		if (roundMode == RoundMode.ROUND_DRAWABLE) {
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
				if (getCropToPadding()) {
					final int scrollX = getScrollX();
					final int scrollY = getScrollY();
					canvas.clipRect(scrollX + getPaddingLeft(), scrollY + getPaddingTop(),
							scrollX + getRight() - getLeft() - getPaddingRight(),
							scrollY + getBottom() - getTop() - getPaddingBottom());
				}
			}

			canvas.translate(getPaddingLeft(), getPaddingTop());
			if (getImageMatrix() != null) {
				Matrix m = new Matrix(getImageMatrix());
				canvas.concat(m);
			}
		}
	}

}


1、默认使用

RoundImageView imageView=new RoundImageView(getApplicationContext());
		imageView.setImageResource(R.drawable.m);
		setContentView(imageView,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

Android神话级圆形图片控件RoundImageView_第1张图片


2、给组件加点偏移

RoundImageView imageView=new RoundImageView(getApplicationContext());
		
		imageView.setPadding(200, 100, 20, 0);
		
		imageView.setImageResource(R.drawable.m);
		setContentView(imageView,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

Android神话级圆形图片控件RoundImageView_第2张图片


国际惯例

————————————————————————————————————————————————————————

作者:薄荷记账  (转载请注明原作者)

简洁   稳定   优雅   无限可能!



你可能感兴趣的:(Android神话级圆形图片控件RoundImageView)