自定义ImageView IM聊天 图片圆角 三角角标
2018-03-29 16:17
316 查看
自定义ImageView IM聊天 图片圆角 三角角标
先看下效果图矩形圆角大小可自行设置 三角角标可设置左右 上下距离可设置 三角的大小可看源码 着需求而定
这里采用的是BitmapShader,BitmapShader是Shader的子类,Shader在三维软件中我们称之为着色器,所以通俗的理解,Shader的作用是给图像着色或者上色,BitmapShader允许我们载入一张图片来给图像着色,具体不做过多的解释,结尾贴出关于Shader的具体使用的文章所以其实根据上面对于BitmapShader的描述,其实就可以对圆角ImageView有一定的思路了吧,画一个圆角矩形,然后把本来画上去的图像着色到圆角矩形上,这样就实现了圆角的ImageView
圆角核心代码
//绘制圆角 mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); float scale = 1.0f; if (!(bitmap.getWidth() == (getWidth() - cornerMarkWidth) && bitmap.getHeight() == getHeight())) { // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; if (AngleLocation == 1 || AngleLocation == 2) { scale = Math.max((getWidth() - cornerMarkWidth) * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight()); } else { scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight()); } } // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.setScale(scale, scale); // 设置变换矩阵 mBitmapShader.setLocalMatrix(mMatrix); // 设置shader rectF.left = getPaddingLeft(); rectF.right = getWidth() - getPaddingRight(); if (AngleLocation == 1) {//画在左边 rectF.left = getPaddingLeft() + cornerMarkWidth; } else if (AngleLocation == 2) {//右边 rectF.right = getWidth() - getPaddingRight() - cornerMarkWidth; } rectF.top = getPaddingTop(); rectF.bottom = getHeight() - getPaddingBottom(); mPaint.setShader(mBitmapShader); canvas.drawRoundRect(rectF, circleRadius, circleRadius, mPaint);
下面就是画三角 分在左边和右边 代码如下
//绘制凸出三角 if (AngleLocation == 2) { path.moveTo(rectF.right, rectF.top + mAnglePaddingTop); path.lineTo(rectF.right + cornerMarkWidth, rectF.top + mAnglePaddingTop + cornerMarkHeight / 2); path.lineTo(rectF.right, rectF.top + mAnglePaddingTop + cornerMarkHeight); path.lineTo(rectF.right, rectF.top + mAnglePaddingTop); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setAntiAlias(true); mPaint.setDither(true); canvas.drawPath(path, mPaint); } else if (AngleLocation == 1) { path.moveTo(rectF.left, rectF.top + mAnglePaddingTop); path.lineTo(rectF.left - cornerMarkWidth, rectF.top + mAnglePaddingTop + cornerMarkHeight / 2); path.lineTo(rectF.left, rectF.top + mAnglePaddingTop + cornerMarkHeight); path.lineTo(rectF.left, rectF.top + mAnglePaddingTop); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setAntiAlias(true); mPaint.setDither(true); canvas.drawPath(path, mPaint); }
这是自定义的属性 也可以自己添加三角的高度 和宽度
<declare-styleable name="IMImageView"> <!--圆角半径--> <attr name="circleRadius" format="dimension" /> <!--左边三角 还是右边三角--> <attr name="AngleLocation" > <enum name="Left" value="1" /> <enum name="Right" value="2" /> <enum name="Gone" value="3" /> </attr> <!--三角距离顶部位置--> <attr name="anglePaddingTop" format="dimension" /> </declare-styleable>
下面是全部的代码
package xxx.xxxx.view.im; package xxx.xxxx.view.im; import android.annotation.SuppressLint; 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.Path; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; import android.util.AttributeSet; import xxxx.xxxx.xxxx.R; import xxxx.xxxx.xxxx.view.ImageView; /** * Created by ZhangYan on 2018/3/28. */ public class IMImageView extends ImageView { private final Context context; private float mCircleRadius; // 1 左边 2 右边 3 隐藏 private int AngleLocation; //三角距离自身顶部的距离 private float mAnglePaddingTop; private Paint mPaint; private BitmapShader mBitmapShader; private Matrix mMatrix; private RectF mRectF; //角标的宽度 private int mCornerMarkWidth = 20; //角标的高度 private int mCornerMarkHeight = 40; private Path mPath; public IMImageView(Context context) { this(context, null); } public IMImageView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public IMImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(attrs); } private void init(AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IMImageView); mCircleRadius = typedArray.getDimensionPixelOffset(R.styleable.IMImageView_circleRadius, 10); AngleLocation = typedArray.getInt(R.styleable.IMImageView_AngleLocation, 1); mAnglePaddingTop = typedArray.getDimension(R.styleable.IMImageView_anglePaddingTop, 10f); typedArray.recycle(); mMatrix = new Matrix(); mPaint = new Paint(); mRectF = new RectF(); mPaint.setAntiAlias(true); mPath = new Path(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (AngleLocation == 1 || AngleLocation == 2) { int size = MeasureSpec.getSize(widthMeasureSpec); widthMeasureSpec = MeasureSpec.makeMeasureSpec(size + mCornerMarkWidth, MeasureSpec.getMode(widthMeasureSpec)); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { Bitmap bitmap = drawableToBitmap(getDrawable()); if (bitmap == null) { return; } //绘制圆角 mBitmapShader = new BitmapShader 4000 (bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); float scale = 1.0f; if (!(bitmap.getWidth() == (getWidth() - mCornerMarkWidth) && bitmap.getHeight() == getHeight())) { // 如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值; if (AngleLocation == 1 || AngleLocation == 2) { scale = Math.max((getWidth() - mCornerMarkWidth) * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight()); } else { scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight()); } } // shader的变换矩阵,我们这里主要用于放大或者缩小 mMatrix.setScale(scale, scale); // 设置变换矩阵 mBitmapShader.setLocalMatrix(mMatrix); // 设置shader mRectF.left = getPaddingLeft(); mRectF.right = getWidth() - getPaddingRight(); if (AngleLocation == 1) {//画在左边 mRectF.left = getPaddingLeft() + mCornerMarkWidth; } else if (AngleLocation == 2) {//右边 mRectF.right = getWidth() - getPaddingRight() - mCornerMarkWidth; } mRectF.top = getPaddingTop(); mRectF.bottom = getHeight() - getPaddingBottom(); mPaint.setShader(mBitmapShader); canvas.drawRoundRect(mRectF, mCircleRadius, mCircleRadius, mPaint); //绘制凸出三角 if (AngleLocation == 2) { mPath.moveTo(mRectF.right, mRectF.top + mAnglePaddingTop); mPath.lineTo(mRectF.right + mCornerMarkWidth, mRectF.top + mAnglePaddingTop + mCornerMarkHeight / 2); mPath.lineTo(mRectF.right, mRectF.top + mAnglePaddingTop + mCornerMarkHeight); mPath.lineTo(mRectF.right, mRectF.top + mAnglePaddingTop); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setAntiAlias(true); mPaint.setDither(true); canvas.drawPath(mPath, mPaint); } else if (AngleLocation == 1) { mPath.moveTo(mRectF.left, mRectF.top + mAnglePaddingTop); mPath.lineTo(mRectF.left - mCornerMarkWidth, mRectF.top + mAnglePaddingTop + mCornerMarkHeight / 2); mPath.lineTo(mRectF.left, mRectF.top + mAnglePaddingTop + mCornerMarkHeight); mPath.lineTo(mRectF.left, mRectF.top + mAnglePaddingTop); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setAntiAlias(true); mPaint.setDither(true); canvas.drawPath(mPath, mPaint); } } private Bitmap drawableToBitmap(Drawable drawable) { if (drawable == null) { return null; } else if (drawable instanceof BitmapDrawable) { return ((BitmapDrawable) drawable).getBitmap(); } else { try { Bitmap bitmap; if (drawable instanceof ColorDrawable) { bitmap = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return bitmap; } catch (Exception var4) { var4.printStackTrace(); return null; } } } }
使用
<xxxx.xxxx.view.im.IMImageView xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" app:anglePaddingTop="@dimen/x20" app:AngleLocation="Right" app:circleRadius="@dimen/x10" android:src="@drawable/img_default_page" android:scaleType="fitXY" />
相关文章推荐
- 分享一个实现图片圆角,圆的自定义的ImageView,尽可能少的减少内存消耗。
- Android自定义圆角ImageView 支持网络图片
- Android自定义圆角ImageView 支持网络图片
- android自定义一圆角ImageView-圆角图片
- 自定义imageview中的圆角和圆形图片
- 实现圆角图片——自定义控ImageView
- Android自定义ImageView实现图片缩放滑动,双击放大缩小,多点触控旋转,圆角矩形,圆形和仿刮刮卡效果
- 自定义imageVIew实现圆角和圆形图,片圆形图片缩小放大正常,圆角图片放大缩小有点问题
- Android实现自定义ImageView的圆角矩形图片效果
- Android自定义圆角矩形图片ImageView
- 自定义圆角的ImageView 还可以实现图片的圆形、椭圆形展示。
- Android imageView 自定义单个或多个角为圆角及圆形图片工具
- 自定义ImageView实现圆角图片和圆形图片
- Android自定义圆角ImageView 支持网络图片
- Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示
- 安卓学习笔记---自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示(矩形圆角加边框)
- Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示
- 自定义ImageView-----可以让图片变圆角
- 自定义ImageView图片切角,切指定的边圆角
- Android开发之自定义圆角矩形图片ImageView的实现