自定义view之RoundImageView

    xiaoxiao2021-03-26  67

    最近,会遇到将图片以圆或者圆角的形式展示的需求,索性就写一个

    这里的思路就是重新绘制imageview,同时要注释显示的类容

    那么几个关键的一确认控件的大小

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (type == TYPE_CIRCLE) { //取高宽最短的做直径 mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = mWidth / 2; //设置view的新的高宽 setMeasuredDimension(mWidth, mWidth); } }

    然后是显示的图片的部分处理,这里要用到Matrix就是利用3x3的矩阵对图片进行放大缩小,以及平移 这里主要是进行百分比处理

    private void setUpShader() { Drawable drawable = getDrawable(); if (drawable == null) return; Bitmap bmp = drawableToBitamp(drawable); // 将bmp作为着色器,就是在指定区域内绘制bmp mBitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); float scale = 1.0f; if (type == TYPE_CIRCLE) { int bSize = Math.min(bmp.getWidth(), bmp.getHeight()); scale = mWidth * 1.0f / bSize; } else if (type == TYPE_ROUND) { scale = Math.max(getWidth() * 1.0f / bmp.getWidth(), getHeight() * 1.0f / bmp.getHeight()); } Log.i("RoundImageView", "setUpShader: "+scale); // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.setScale(scale, scale); // 设置变换矩阵 mBitmapShader.setLocalMatrix(mMatrix); // 设置shader mBitmapPaint.setShader(mBitmapShader); }

    这里直接贴出代码 首先是attrs

    <?xml version="1.0" encoding="utf-8"?> <resources> <attr name="borderRadius" format="dimension" /> <attr name="type"> <enum name="circle" value="0" /> <enum name="round" value="1" /> </attr> <declare-styleable name="RoundImageView"> <attr name="borderRadius" /> <attr name="type" /> </declare-styleable> </resources> package com.example.admin.roundimageview; 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; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.ImageView; /** * Created by admin on 2017/2/20. */ public class RoundImageView extends ImageView { /** 图片的类型,圆形or圆角 */ private int type; private static final int TYPE_CIRCLE = 0; private static final int TYPE_ROUND = 1; /** 圆角大小的默认值 */ private static final int BODER_RADIUS_DEFAULT = 10; /** * 圆角的大小 */ private int mBorderRadius; /** * 绘图的Paint */ private Paint mBitmapPaint; /** * 圆角的半径 */ private int mRadius; /** * 3x3 矩阵,主要用于缩小放大 */ private Matrix mMatrix; /** * 渲染图像,使用图像为绘制图形着色 */ private BitmapShader mBitmapShader; /** * view的宽度 */ private int mWidth; private RectF mRoundRect; public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); mMatrix = new Matrix(); mBitmapPaint = new Paint(); mBitmapPaint.setAntiAlias(true); 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(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (type == TYPE_CIRCLE) { //取高宽最短的做直径 mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight()); mRadius = mWidth / 2; //设置view的新的高宽 setMeasuredDimension(mWidth, mWidth); } } private void setUpShader() { Drawable drawable = getDrawable(); if (drawable == null) return; Bitmap bmp = drawableToBitamp(drawable); // 将bmp作为着色器,就是在指定区域内绘制bmp mBitmapShader = new BitmapShader(bmp, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); float scale = 1.0f; if (type == TYPE_CIRCLE) { int bSize = Math.min(bmp.getWidth(), bmp.getHeight()); scale = mWidth * 1.0f / bSize; } else if (type == TYPE_ROUND) { scale = Math.max(getWidth() * 1.0f / bmp.getWidth(), getHeight() * 1.0f / bmp.getHeight()); } // shader的变换矩阵,我们这里主要用于放大或者缩小 这里主要是按照一定的比例是放大或缩小图片放到imgaview'上面 mMatrix.setScale(scale, scale); // 设置变换矩阵 mBitmapShader.setLocalMatrix(mMatrix); // 设置shader mBitmapPaint.setShader(mBitmapShader); } 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; } @Override protected void onDraw(Canvas canvas) { if (getDrawable() == null) return; setUpShader(); if (type == TYPE_ROUND) { canvas.drawRoundRect(mRoundRect, mBorderRadius, mBorderRadius, mBitmapPaint); } else { canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint); } } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 圆角图片的范围 if (type == TYPE_ROUND) mRoundRect = new RectF(0, 0, getWidth(), getHeight()); } }

    用法

    <com.example.admin.roundimageview.RoundImageView android:layout_width="95dp" android:layout_height="wrap_content" app:type="circle" android:src="@mipmap/ic_launcher" android:layout_weight="0.13" /> <com.example.admin.roundimageview.RoundImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:type="round" app:borderRadius="100dp" android:src="@mipmap/ic_launcher"/>

    (今天有点 累,详细说明以后补上)

    转载请注明原文地址: https://ju.6miu.com/read-350067.html

    最新回复(0)