圆形头像之BitmapShader,Matrix实现篇
来源:互联网 发布:动态规划的最优化原理 编辑:程序博客网 时间:2024/04/29 22:10
利用BitmapShader实现圆形头像的功能,可以定义边框的颜色、大小,支持padding
效果图:(为了方便看一些padding我加了黄色的背景,在onDraw()方法中第一行,去掉就可以了)
代码上该注释的地方已经注释的很清楚了
来贴一下代码:
package com.shj.view.image;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;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.shj.test.R;public class RoundImageView extends ImageView {private int borderColor;// 圆形头像的边框颜色private int borderWidth;// 圆形头像的边框宽度private Paint mBitmapPaint;// 绘制图像的Paintprivate Paint mBorderPaint;private Matrix mMatrix;// 图像矩阵,本身是一个3*3矩阵 private int mRadius;private int mImgWidth;public RoundImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundImageView(Context context) {this(context, null);}public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initAttrs(context, attrs);mBitmapPaint = new Paint();mBorderPaint = new Paint();mMatrix = new Matrix();mBitmapPaint.setAntiAlias(true);mBorderPaint.setAntiAlias(true);}private void initAttrs(Context context, AttributeSet attrs) {TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);borderColor = a.getColor(R.styleable.RoundImageView_border_color, Color.parseColor("#ffffff"));borderWidth = a.getDimensionPixelSize(R.styleable.RoundImageView_border_width, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 0, getResources().getDisplayMetrics()));a.recycle();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//写好一个控件自定义View,写出一个能用的自定义View不易啊。。。 // 虽然测量这块儿寥寥几行代码,但是还得心细啊。。int imgHeight = setMeasureHeight(heightMeasureSpec)-getPaddingTop() - getPaddingBottom()-borderWidth*2;int imgWidth = setMeasureWidth(widthMeasureSpec) - getPaddingLeft() - getPaddingRight()-borderWidth*2;if(imgHeight<imgWidth){mImgWidth = imgHeight;mRadius = mImgWidth/2;}else{mImgWidth = imgWidth;mRadius = mImgWidth/2;}setMeasuredDimension(setMeasureWidth(widthMeasureSpec),setMeasureHeight(heightMeasureSpec));}private int setMeasureHeight(int heightMeasureSpec) {int height = 0;int minHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 56, getResources().getDisplayMetrics());int specMode = MeasureSpec.getMode(heightMeasureSpec);int specSize = MeasureSpec.getSize(heightMeasureSpec);switch (specMode) {case MeasureSpec.EXACTLY:height = (specSize < minHeight ? minHeight : specSize);// 此处我是设置了EXACTLY的值,仅是圆形图片大小的值break;case MeasureSpec.AT_MOST:height = minHeight + getPaddingTop() + getPaddingBottom();break;case MeasureSpec.UNSPECIFIED:height = minHeight + getPaddingTop() + getPaddingBottom();break;}return height;}private int setMeasureWidth(int widthMeasureSpec) {int width = 0;int minWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 56, getResources().getDisplayMetrics());int specMode = MeasureSpec.getMode(widthMeasureSpec);int specSize = MeasureSpec.getSize(widthMeasureSpec);switch (specMode) {case MeasureSpec.EXACTLY:width = (specSize < minWidth ? minWidth : specSize);break;case MeasureSpec.AT_MOST:width = minWidth + getPaddingLeft() + getPaddingRight();break;case MeasureSpec.UNSPECIFIED:width = minWidth + getPaddingRight() + getPaddingLeft();break;}return width;}@Overrideprotected void onDraw(Canvas canvas) {this.setBackgroundColor(Color.YELLOW);if (getDrawable() == null) {return;}setShader();canvas.drawCircle(mRadius + borderWidth + getPaddingLeft(), mRadius + borderWidth + getPaddingTop(), mRadius, mBitmapPaint);mBorderPaint.setColor(borderColor);mBorderPaint.setStyle(Paint.Style.STROKE);mBorderPaint.setStrokeWidth(borderWidth / 2);canvas.drawCircle(mRadius + borderWidth + getPaddingLeft(), mRadius + borderWidth + getPaddingTop(), mRadius + borderWidth / 2, mBorderPaint);}/** * 初始化bitmapShader */private void setShader() {Drawable drawable = getDrawable();Bitmap bmp = drawableToBitmap(drawable); BitmapShader mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP);float scale = 1.0f;// 去取bitmap中宽度和高度中更小的,为了使图像缩放之后,可以填充满控件的空间, // 此处切记要乘以1.0f,,这种低级错误写的时候又犯了一次。scale = mImgWidth * 1.0f / (Math.min(bmp.getWidth(), bmp.getHeight()));mMatrix.setScale(scale, scale);mMatrix.postTranslate(getPaddingLeft()+borderWidth, getPaddingTop()+borderWidth);//这里使用了Matrix的后乘进行效果叠加, // 使图像根据padding进行位移mBitmapShader.setLocalMatrix(mMatrix);mBitmapPaint.setShader(mBitmapShader);}/** * 将Drawable转变为bitmap */private Bitmap drawableToBitmap(Drawable drawable) {if (drawable instanceof BitmapDrawable) {BitmapDrawable bd = (BitmapDrawable) drawable;return bd.getBitmap();}int h = drawable.getIntrinsicHeight();int w = drawable.getIntrinsicWidth();Bitmap bitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);// 建立对应的bitmap画布drawable.setBounds(0, 0, w, h);// 此处的setBounds是指,drawable将在canvas的0,0,w,h矩形区域内drawable.draw(canvas);// 将drawable的内容画到画布中去return bitmap;}}
自定义属性:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="RoundImageView"> <attr name="border_width" format="dimension"/> <attr name = "border_color" format="color"/> </declare-styleable></resources>
<com.shj.view.image.RoundImageView android:id="@+id/img1" android:layout_width="128dp" android:layout_height="128dp" android:src="@mipmap/head" app:border_color="@color/colorAccent" app:border_width="2dp" android:paddingLeft="8dp" android:paddingTop="60dp"/> <com.shj.view.image.RoundImageView android:id="@+id/img2" android:layout_marginTop="8dp" android:layout_below="@+id/img1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/head" android:paddingLeft="16dp" android:paddingTop="8dp"/>
如果试的时候出现什么问题,烦请说一下哈,一起进步。
0 0
- 圆形头像之BitmapShader,Matrix实现篇
- BitmapShader实现圆形头像
- 使用BitmapShader显示圆形头像
- 精简版BitmapShader实现圆形头像和圆角方形头像
- 我的Android笔记--使用BitmapShader实现可调灰色圆形、圆角头像
- 用BitmapShader实现圆形图片
- 利用 BitmapShader 制作自带边框圆形头像
- IOS之圆形头像的实现
- 使用BitmapShader实现图片的圆形、圆角
- 使用BitmapShader实现圆形,圆角图片
- Android BitmapShader 实现圆形、圆角图片
- Android BitmapShader实现圆角、圆形ImageView
- BitmapShader渲染器:实现圆形图片
- iOS实现圆形头像
- iOS实现圆形头像
- iOS实现圆形头像
- Android实现圆形头像
- 圆形头像显示实现
- C# 中的抽象类中的 静态方法
- centos 安装phpredis扩展
- leetcode_198. House Robber 抢劫不相邻的房子,使得抢到的金钱数目最大, 动态规划
- 关于浮点数的精度与取值范围的问题
- [Linux C编程]消息队列实现同时通信
- 圆形头像之BitmapShader,Matrix实现篇
- 营养与碘
- POI2014
- [PHP]九九乘法表实现三种方式
- linux 进程通信—管道通信
- 分页查询spring boot+spring data+ajax
- Android init进程中鲜为人知的charger mode 模式
- codeforces 43E Race
- Leetcode-120. Triangle