记录一个自定义Imageview

记录一个自定义imageview  根据网上找到的圆角Imageview 做的修改。可实现焦点放大和缩小。并且获取焦点会展示阴影和白框。


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;

import com.example.administrator.mytvapplication.R;


/**
 * http://blog.csdn.net/lmj623565791/article/details/41967509
 * 自定义圆角imageview
 */
public class RoundImageView extends AppCompatImageView
{
	/**
	 * 图片的类型,圆形or圆角
	 */
	private int type;
	public static final int TYPE_CIRCLE = 0;
	public static final int TYPE_ROUND = 1;
	/**
	 * 圆角大小的默认值
	 */
	private static final int BODER_RADIUS_DEFAULT = 10;
	/**
	 * 圆角的大小
	 */
	private int mBorderRadius;

	/**
	 * 绘图的Paint
	 */
	private Paint mBitmapPaint;

	/**
	 * 边框paint
	 */
	Paint borderPaint;

	/**
	 * 圆角的半径
	 */
	private int mRadius;
	/**
	 * 3x3 矩阵,主要用于缩小放大
	 */
	private Matrix mMatrix;
	/**
	 * 渲染图像,使用图像为绘制图形着色
	 */
	private BitmapShader mBitmapShader;
	/**
	 * view的宽度
	 */
	private int mWidth;
	private RectF mRoundRect;

	/**
	 * 创建底层画布
	 *
	 */
	private Canvas  bottomCanvas;
	/**
	 * 底层画布bitmap
	 */
	private Bitmap bottomBitmap=null;

	/**
	 *
	 * 底层画布rect
	 */
	private RectF  bottomR;

	private 	int borderW=3;


	public RoundImageView(Context context, AttributeSet attrs)
	{

		super(context, attrs);
		mMatrix = new Matrix();
		mBitmapPaint = new Paint();
		mBitmapPaint.setAntiAlias(true);
		 borderPaint=new Paint();
		borderPaint.setColor(Color.WHITE);
		borderPaint.setAntiAlias(true);
		borderPaint.setStrokeWidth(4f);
		borderPaint.setShadowLayer(5f, 0, 0, Color.BLACK);

		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.RoundImageView);

		mBorderRadius = a.getDimensionPixelSize(
				R.styleable.RoundImageView_borderRadius, (int) TypedValue
						.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
								BODER_RADIUS_DEFAULT, getResources()
										.getDisplayMetrics()));// 默认为10dp
		type = a.getInt(R.styleable.RoundImageView_type, TYPE_CIRCLE);// 默认为Circle

		a.recycle();
	}

	public RoundImageView(Context context)
	{
		this(context, null);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		/**
		 * 如果类型是圆形,则强制改变view的宽高一致,以小值为准
		 */
		if (type == TYPE_CIRCLE)
		{
			mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
			mRadius = mWidth / 2;
			setMeasuredDimension(mWidth, mWidth);
		}
		bottomBitmap = Bitmap.createBitmap(getMeasuredWidth()+8,
				getMeasuredHeight()+8, Bitmap.Config.ARGB_8888);
		bottomCanvas =new Canvas(bottomBitmap);
		Log.i("2024",getMeasuredWidth()+4+"---ac"+(getMeasuredHeight()+4));

	}

	/**
	 * 初始化BitmapShader
	 */
	private void setUpShader()
	{
		Drawable drawable = getDrawable();
		if (drawable == null)
		{
			return;
		}

		Bitmap bmp = drawableToBitamp(drawable);
		// 将bmp作为着色器,就是在指定区域内绘制bmp
		mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP);
		float scale = 1.0f;
		if (type == TYPE_CIRCLE)
		{
			// 拿到bitmap宽或高的小值
			int bSize = Math.min(bmp.getWidth(), bmp.getHeight());
			scale = mWidth * 1.0f / bSize;

		} else if (type == TYPE_ROUND)
		{
//			Log.e("TAG",
//					"b'w = " + bmp.getWidth() + " , " + "b'h = "
//							+ bmp.getHeight());
			if (!(bmp.getWidth() == getWidth() && bmp.getHeight() == getHeight()))
			{
				// 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;
				scale = Math.max(getWidth() * 1.0f / bmp.getWidth(),
						getHeight() * 1.0f / bmp.getHeight());
			}

		}
		getmWidth=getWidth()*scale;
		getGetmWidth=getHeight()*scale;
		// shader的变换矩阵,我们这里主要用于放大或者缩小
		mMatrix.setScale(scale, scale);
		// 设置变换矩阵
		mBitmapShader.setLocalMatrix(mMatrix);
		// 设置shader
		mBitmapPaint.setShader(mBitmapShader);
	}
	float  getmWidth;
	float getGetmWidth;
	@Override
	protected void onDraw(final Canvas canvas)
	{
//		Log.e("TAG", "onDraw");
		if (getDrawable() == null)
		{
			return;
		}
		if(bottomBitmap!=null){
			Paint bottomPaint=new Paint();
			bottomPaint.setAntiAlias(true);
			bottomPaint.setColor(Color.WHITE);
			canvas.drawBitmap(bottomBitmap,0,0,bottomPaint);
		}
		setUpShader();

		if (type == TYPE_ROUND)
		{
			canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius,
					mBitmapPaint);
//
			setOnFocusChangeListener(new OnFocusChangeListener() {
				@Override
				public void onFocusChange(View v, boolean hasFocus) {
					if(hasFocus){
								 bottomCanvas.drawRoundRect(bottomR,mBorderRadius,mBorderRadius
								,borderPaint);
						if(Build.VERSION.SDK_INT>=21){
							//太高z抽
							ViewCompat.animate(RoundImageView.this).scaleX(1.30f).scaleY(1.30f).translationZ(1).start();
						}else{
							ViewCompat.animate(RoundImageView.this).scaleX(1.30f).scaleY(1.30f).start();
							/*ViewGroup parent = (ViewGroup) RoundImageView.this.getParent();
							parent.requestLayout();
							parent.invalidate();*/
						}
					}else{
						//清屏
						borderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
						bottomCanvas.drawPaint(borderPaint);
						borderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
						if (Build.VERSION.SDK_INT >= 21) {
							ViewCompat.animate(RoundImageView.this).scaleX(1.0f).scaleY(1.0f).translationZ(0).start();
						} else {
							ViewCompat.animate(RoundImageView.this).scaleX(1.0f).scaleY(1.0f).start();
							/*ViewGroup parent = (ViewGroup) RoundImageView.this.getParent();
							parent.requestLayout();
							parent.invalidate();*/
						}
					}
				}
			});
		} else
		{
			canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);
			// drawSomeThing(canvas);
		}
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{
		super.onSizeChanged(w, h, oldw, oldh);
		int boder=dp2px(borderW);
		// 圆角图片的范围
		if (type == TYPE_ROUND)
			mRoundRect = new RectF(6, 6, w-6, h-6);
		bottomR=new RectF();
		bottomR.set(4,4,w-4,h-4);
	}

	/**
	 * drawable转bitmap
	 * 
	 * @param drawable
	 * @return
	 */
	private Bitmap drawableToBitamp(Drawable drawable)
	{
		if (drawable instanceof BitmapDrawable)
		{
			BitmapDrawable bd = (BitmapDrawable) drawable;
			return bd.getBitmap();
		}
		int w = drawable.getIntrinsicWidth();
		int h = drawable.getIntrinsicHeight();
		Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, w, h);
		drawable.draw(canvas);
		return bitmap;
	}

	private static final String STATE_INSTANCE = "state_instance";
	private static final String STATE_TYPE = "state_type";
	private static final String STATE_BORDER_RADIUS = "state_border_radius";

	@Override
	protected Parcelable onSaveInstanceState()
	{
		Bundle bundle = new Bundle();
		bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
		bundle.putInt(STATE_TYPE, type);
		bundle.putInt(STATE_BORDER_RADIUS, mBorderRadius);
		return bundle;
	}

	@Override
	protected void onRestoreInstanceState(Parcelable state)
	{
		if (state instanceof Bundle)
		{
			Bundle bundle = (Bundle) state;
			super.onRestoreInstanceState(((Bundle) state)
					.getParcelable(STATE_INSTANCE));
			this.type = bundle.getInt(STATE_TYPE);
			this.mBorderRadius = bundle.getInt(STATE_BORDER_RADIUS);
		} else
		{
			super.onRestoreInstanceState(state);
		}

	}

	public void setBorderRadius(int borderRadius)
	{
		int pxVal = dp2px(borderRadius);
		if (this.mBorderRadius != pxVal)
		{
			this.mBorderRadius = pxVal;
			invalidate();
		}
	}

	public void setType(int type)
	{
		if (this.type != type)
		{
			this.type = type;
			if (this.type != TYPE_ROUND && this.type != TYPE_CIRCLE)
			{
				this.type = TYPE_CIRCLE;
			}
			requestLayout();
		}

	}

	public int dp2px(int dpVal)
	{
		return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
				dpVal, getResources().getDisplayMetrics());
	}

}


猜你喜欢

转载自blog.csdn.net/ImTryCatchException/article/details/79272130