Android实现动态圆环的图片头像控件
先看效果图:
现在大部分的app上难免会使用到圆形头像,所以今天我给大家分享一个单独使用的,并且周围带有圆环动画的花哨圆形头像控件,本控件是在圆形头像控件基础上实现的,只是在其周围再画一些不同大小的圆而已,就可以实现如图的效果。
圆形头像的基本原理是将设置的资源文件转化成bitmap,然后通过bitmapshader类将bitmap成为paint的渲染器,然后在ondraw()中通过canvas.drawcircle(rx,ry,radius,paint);画布上画圆,而这个圆就是形成了圆形头像。
在xml中通过src设置的资源文件在imageview的setimagedrawable(drawable)方法中可以得到drawable类型的图像,然后再将drawable转成bitmap就可以了
public void setimagedrawable(drawable drawable) { super.setimagedrawable(drawable); mbitmap = getbitmapfromdrawable(drawable); setup(); } private bitmap getbitmapfromdrawable(drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof bitmapdrawable) { //从bitmap中间裁剪出最大的正方形 bitmap bitmap = ((bitmapdrawable) drawable).getbitmap(); return getmaxsquarecenter(bitmap); //return ((bitmapdrawable) drawable).getbitmap(); } try { bitmap bitmap; if (drawable instanceof colordrawable) { bitmap = bitmap.createbitmap(colordrawable_dimension, colordrawable_dimension, bitmap_config); } else { int min = math.min(drawable.getintrinsicwidth(), drawable.getintrinsicheight()); bitmap = bitmap.createbitmap(min, min, bitmap_config); } canvas canvas = new canvas(bitmap); int left,top,right,buttom; int width = canvas.getwidth(); int height = canvas.getheight(); int abs = math.abs(width - height); if(width <= height){ left = 0; top = (height - abs) / 2; right = width; buttom = height - top; }else{ left = (width - abs) / 2; top = 0; right = width - left; buttom = height; } //drawable.setbounds(0, 0, canvas.getwidth(), canvas.getheight()); drawable.setbounds(left, top, right, buttom); drawable.draw(canvas); return bitmap; } catch (outofmemoryerror e) { return null; } } /** * 从bitmap中间裁剪出最大的正方形 * @param bitmap * @return */ private bitmap getmaxsquarecenter(bitmap bitmap){ int w = bitmap.getwidth(); // 得到图片的宽,高 int h = bitmap.getheight(); int cropwidth = w >= h ? h : w;// 裁切后所取的正方形区域边长 return bitmap.createbitmap(bitmap, (w - cropwidth)/2 , (h - cropwidth)/2, cropwidth, cropwidth, null, false); }
获取到bitmap对象后就可以将bitmap缩小一倍后,在将其画在画布上,这样就有地方来画周围的圆环了。
private void updateshadermatrix() { float scale; float dx = 0; float dy = 0; mshadermatrix.set(null); if (mbitmapwidth * mdrawablerect.height() > mdrawablerect.width() * mbitmapheight) { scale = mdrawablerect.height() / (float) mbitmapheight / 2; //将图片缩放在正中间 缩小一倍 dx = (mdrawablerect.width() - mbitmapwidth * scale) * 0.5f; } else { scale = mdrawablerect.width() / (float) mbitmapwidth / 2; //将图片缩放在正中间 缩小一倍 dy = (mdrawablerect.height() - mbitmapheight * scale) * 0.5f; } mshadermatrix.setscale(scale , scale ); //在x轴上平移mdrawableradius,就在正中间了 mshadermatrix.posttranslate((int) (dx + 0.5f) + mborderwidth + mdrawableradius, (int) (dy + 0.5f) + mborderwidth); mbitmapshader.setlocalmatrix(mshadermatrix); }
下面就是画图片周围的圆环了,就是在图片的外围画两个圆,一个半径大点,颜色浅点,一个半径小点,颜色深点就可以了,然后通过handler通过延时操作,不断的改变两个圆的半径大小和颜色的深浅,重绘就可以了
private float mchangerateborder;//记录外圆执行动画时半径变化率 private float mchangerateouter;//记录内圆执行动画时半径变化率 private float mchangerateinner;//记录图片边框执行动画时半径变化率 private float mchangerange;//变化范围,view半径的1/6 //*******执行动画*******// //外圆执行动画时半径变化率 private float mrateouter[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f ,0.92f,0.88f,0.85f,0.82f,0.76f,0.72f,0.68f,0.60f,0.54f,0.48f, 0.40f,0.33f,0.28f,0.20f}; //内圆执行动画时半径变化率 private float mrateinner[] = { -1,-1,-1,-1,-1, 0,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f ,0.92f,0.88f,0.84f,0.80f,0.72f,0.67f,0.60f,0.54f,0.48f,-1f ,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f}; //图片边框执行动画时半径变化率 private float mrateborder[] = { 0,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f ,0.92f,0.90f,0.84f,0.78f,0.72f,0.64f,0.58f,-1f,-1f,-1f ,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f ,-1f,-1f,-1f,-1f}; private int mrateindex;//动画变化率的索引
handler不断改变半径的变化率和画笔的颜色
/** * 按住执行动画 */ private handler mhandler = new handler(){ @override public void handlemessage(message msg) { super.handlemessage(msg); int index = mrateindex ++; mchangerateborder = mrateborder[(index)% mrateborder.length]; setpaintcorlor(mborderpaint,mchangerateborder,default_border_color); setpaintalpha(mborderpaint,(index)% mrateborder.length,mrateborder); mchangerateouter = mrateouter[(index) % mrateouter.length]; setpaintcorlor(mouterpaint,mchangerateouter,mouterpaintcolor); setpaintalpha(mouterpaint,(index) % mrateouter.length,mrateouter); mchangerateinner = mrateinner[(index) % mrateinner.length]; setpaintcorlor(minnerpaint,mchangerateinner,minnerpaintcolor); setpaintalpha(minnerpaint,(index) % mrateinner.length,mrateinner); //system.out.println("---------mchangerate:"+mchangerateborder); invalidate(); mhandler.removecallbacksandmessages(null); mhandler.sendemptymessagedelayed(0,30); } };
每执行一次handlemessage()就会触发(invalidate())view重绘,ondraw中不断的重绘,只需改变每个circle的半径即可
@override protected void ondraw(canvas canvas) { if (getdrawable() == null) { return; } //画动画的图形 canvas.drawcircle(getwidth() / 2,getheight() / 2,getchangeradiusouter(mouterradius),mouterpaint); canvas.drawcircle(getwidth() / 2,getheight() / 2,getchangeradiusinner(minnerradius),minnerpaint); canvas.drawcircle(getwidth() / 2, getheight() / 2, mdrawableradius, mbitmappaint); canvas.drawcircle(getwidth() / 2, getheight() / 2, getchangeradiusborder(mborderradius), mborderpaint); }
根据handler中给的变化率来计算每个circle的半径
private float getchangeradiusborder(float radius){ return mchangerateborder * mchangerange + radius; } private float getchangeradiusouter(float radius){ return mchangerateouter * mchangerange + radius; } private float getchangeradiusinner(float radius){ return mchangerateinner * mchangerange + radius; }
这样在不断的向handler发送消息时,也就会不断的触发重绘,不断改变外围圆的大小,形成上图所见的动画效果
如下四个方法,就是来控制圆环所展示的不同状态
/** * 开始动画 */ public void startanim(){ //让外围的圆环动起来 mhandler.sendemptymessagedelayed(0,30); } /** * 停止动画 */ public void stopanim(){ //停止外圆环的动画,展示默认的大小 mhandler.removecallbacksandmessages(null); mchangerateborder = 0; mchangerateouter = 0; mchangerateinner = 0; initanimcolor(); enteranim(); } /** * 进入动画 */ public void enteranim(){ //展示外圆环,显示默认大小 mhandlerenter.sendemptymessage(0); } /** * 退出动画 */ public void exitanim(){ //隐藏外圆环 mhandlerexit.sendemptymessage(0); }
好了,动态头像到这基本就实现了,进入动画和退出动画的代码就不贴出来分析了,如果发现bug或者有任何意见欢迎留言。
完整源码
import android.content.context; 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.rectf; import android.graphics.shader; import android.graphics.drawable.bitmapdrawable; import android.graphics.drawable.colordrawable; import android.graphics.drawable.drawable; import android.os.handler; import android.os.message; import android.util.attributeset; import android.widget.imageview; /** * created by cj_28 on 2016/10/15. */ public class dynamicavatarview extends imageview { private static final scaletype scale_type = scaletype.center_crop; private static final int colordrawable_dimension = 1; private static final bitmap.config bitmap_config = bitmap.config.argb_8888; private bitmap mbitmap; private bitmapshader mbitmapshader; private final matrix mshadermatrix = new matrix(); private final paint mbitmappaint = new paint(); private final paint mborderpaint = new paint(); private final paint mouterpaint = new paint(); private final paint minnerpaint = new paint(); private static final int default_border_width = 3; private static final int default_border_color = color.white; private static final int outer_paint_color = color.parsecolor("#55ffffff"); private static final int inner_paint_color = color.parsecolor("#66ffffff"); private int mbordercolor = default_border_color; private int mborderwidth = default_border_width; private int mouterpaintcolor = outer_paint_color; private int minnerpaintcolor = inner_paint_color; private int mbitmapwidth; private int mbitmapheight; private final rectf mdrawablerect = new rectf(); private final rectf mborderrect = new rectf(); private float mdrawableradius;//显示的图片 private float mborderradius;//..//显示的图片上的边框 private float mouterradius;//外层动画 private float minnerradius;//..//内层动画 private float mrealdrawableradius;//这是view没有被缩放之前的mdrawableradius的半径 private float mrealborderradius;//.. private boolean mready; private boolean msetuppending; private float mchangerateborder;//记录外圆执行动画时半径变化率 private float mchangerateouter;//记录内圆执行动画时半径变化率 private float mchangerateinner;//记录图片边框执行动画时半径变化率 private float mchangerange;//变化范围,view半径的1/6 //*******执行动画*******// //外圆执行动画时半径变化率 private float mrateouter[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f ,0.92f,0.88f,0.85f,0.82f,0.76f,0.72f,0.68f,0.60f,0.54f,0.48f, 0.40f,0.33f,0.28f,0.20f}; //内圆执行动画时半径变化率 private float mrateinner[] = { -1,-1,-1,-1,-1, 0,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f ,0.92f,0.88f,0.84f,0.80f,0.72f,0.67f,0.60f,0.54f,0.48f,-1f ,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f}; //图片边框执行动画时半径变化率 private float mrateborder[] = { 0,0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,1.0f ,0.92f,0.90f,0.84f,0.78f,0.72f,0.64f,0.58f,-1f,-1f,-1f ,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f,-1f ,-1f,-1f,-1f,-1f}; //private int mcolor[] = {0x55ffffff,0x44ffffff,0x33ffffff,0x22ffffff,0x11ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff,0x00ffffff}; private int mrateindex;//动画变化率的索引 //*******进入动画*******// //外圆执行动画时半径变化率 private float mrateouterenter[] = { -2,-2,//外圆要缩小2个mchangerange才会完全隐藏 -2,-2,-2,-2,-2, -0.8f,-0.6f,-0.4f,-0.2f,-0.1f, 0,0.1f,0.2f,0.3f,0.4f,0.5f ,0.44f,0.4f,0.35f,0.3f,0.25f ,0.20f,0.15f,0.1f,0.0f}; //内圆执行动画时半径变化率 private float mrateinnerenter[] = { -1,-1,//外圆要缩小1个mchangerange才会完全隐藏 -0.8f,-0.6f,-0.4f,-0.2f,-0.1f, 0,0.1f,0.2f,0.3f,0.35f,0.4f ,0.45f,0.5f,0.45f,0.4f,0.35f ,0.3f,0.25f,0.2f,0.15f,0.1f ,0.05f,0f,0f,0f}; private int mrateindexenter;//进入动画变化率的索引 //*******退出动画*******// //外圆执行动画时半径变化率 private float mrateouterexit[] = { 0.0f,-0.2f,-0.4f,-0.6f,-0.8f ,-1f,-1.2f,-1.4f,-1.6f,-1.8f ,-2f}; //内圆执行动画时半径变化率 private float mrateinnerexit[] = { 0.0f,-0.1f,-0.2f,-0.3f,-0.4f ,-0.5f,-0.6f,-0.7f,-0.8f,-0.9f ,-1f}; private int mrateindexexit;//进入动画变化率的索引 /** * 按住执行动画 */ private handler mhandler = new handler(){ @override public void handlemessage(message msg) { super.handlemessage(msg); int index = mrateindex ++; mchangerateborder = mrateborder[(index)% mrateborder.length]; setpaintcorlor(mborderpaint,mchangerateborder,default_border_color); setpaintalpha(mborderpaint,(index)% mrateborder.length,mrateborder); mchangerateouter = mrateouter[(index) % mrateouter.length]; setpaintcorlor(mouterpaint,mchangerateouter,mouterpaintcolor); setpaintalpha(mouterpaint,(index) % mrateouter.length,mrateouter); mchangerateinner = mrateinner[(index) % mrateinner.length]; setpaintcorlor(minnerpaint,mchangerateinner,minnerpaintcolor); setpaintalpha(minnerpaint,(index) % mrateinner.length,mrateinner); //system.out.println("---------mchangerate:"+mchangerateborder); invalidate(); mhandler.removecallbacksandmessages(null); mhandler.sendemptymessagedelayed(0,30); } }; private handler mhandlerenter = new handler(){ @override public void handlemessage(message msg) { super.handlemessage(msg); int index = mrateindexenter ++; if(index >= mrateouterenter.length) { mrateindexenter = 0; mhandlerenter.removecallbacksandmessages(null); return; } mchangerateouter = mrateouterenter[(index) % mrateouterenter.length]; mchangerateinner = mrateinnerenter[(index) % mrateinnerenter.length]; invalidate(); mhandlerenter.removecallbacksandmessages(null); mhandlerenter.sendemptymessagedelayed(0,20); } }; private handler mhandlerexit = new handler(){ @override public void handlemessage(message msg) { super.handlemessage(msg); int index = mrateindexexit ++; if(index >= mrateouterexit.length) { mrateindexexit = 0; mhandlerexit.removecallbacksandmessages(null); return; } mchangerateouter = mrateouterexit[(index) % mrateouterexit.length]; mchangerateinner = mrateinnerexit[(index) % mrateinnerexit.length]; invalidate(); mhandlerexit.removecallbacksandmessages(null); mhandlerexit.sendemptymessagedelayed(0,20); } }; /** * 设置outer和inner的画笔颜色 * @param paint * @param rate * @param color */ private void setpaintcorlor(paint paint,float rate,int color){ if(rate < 0){ paint.setcolor(color.transparent); }else{ paint.setcolor(color); } } /** * 设置透明度 * @param paint * @param index * @param rate */ private void setpaintalpha(paint paint,int index,float[] rate){ int pre = index -1; if(pre >= 0 ){ if(rate[pre] > rate[index] && rate[index] > 0){ int color = paint.getcolor(); int colortransparent = color & 0xff000000; int colorvalue = color & 0x00ffffff; colortransparent = colortransparent >>> 7; paint.setcolor((int)(rate[index] * colortransparent) << 7 | colorvalue); } } } public dynamicavatarview(context context) { this(context,null); } public dynamicavatarview(context context, attributeset attrs) { this(context, attrs,0); } public dynamicavatarview(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); super.setscaletype(scale_type); //可以执行了 mready = true; if (msetuppending) { setup(); msetuppending = false; } } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { int widthmode = measurespec.getmode(widthmeasurespec); int widthsize = measurespec.getsize(widthmeasurespec); int heightmode = measurespec.getmode(heightmeasurespec); int heightsize = measurespec.getsize(heightmeasurespec); int size = math.min(widthsize, heightsize); super.onmeasure(measurespec.makemeasurespec(size,widthmode), measurespec.makemeasurespec(size,heightmode)); } @override protected void onlayout(boolean changed, int left, int top, int right, int bottom) { super.onlayout(changed, left, top, right, bottom); enteranim(); } @override protected void ondraw(canvas canvas) { if (getdrawable() == null) { return; } //画动画的图形 canvas.drawcircle(getwidth() / 2,getheight() / 2,getchangeradiusouter(mouterradius),mouterpaint); canvas.drawcircle(getwidth() / 2,getheight() / 2,getchangeradiusinner(minnerradius),minnerpaint); canvas.drawcircle(getwidth() / 2, getheight() / 2, mdrawableradius, mbitmappaint); canvas.drawcircle(getwidth() / 2, getheight() / 2, getchangeradiusborder(mborderradius), mborderpaint); } private float getchangeradiusborder(float radius){ return mchangerateborder * mchangerange + radius; } private float getchangeradiusouter(float radius){ return mchangerateouter * mchangerange + radius; } private float getchangeradiusinner(float radius){ return mchangerateinner * mchangerange + radius; } private void initanimcolor(){ mouterpaint.setstyle(paint.style.fill); mouterpaint.setantialias(true); mouterpaint.setcolor(mouterpaintcolor); minnerpaint.setstyle(paint.style.fill); minnerpaint.setantialias(true); minnerpaint.setcolor(minnerpaintcolor); //图片边框(默认白色) mborderpaint.setcolor(mbordercolor); mouterradius = mrealborderradius / 6 * 5; minnerradius = mrealborderradius / 6 * 4; mchangerange = mrealborderradius / 6; mrateindex = 0; } /** * 开始动画 */ public void startanim(){ mhandler.sendemptymessagedelayed(0,30); } /** * 停止动画 */ public void stopanim(){ mhandler.removecallbacksandmessages(null); mchangerateborder = 0; mchangerateouter = 0; mchangerateinner = 0; // mborderpaint.setcolor(default_border_color); // mouterpaint.setcolor(mouterpaintcolor); // minnerpaint.setcolor(minnerpaintcolor); // mrateindex = 0; initanimcolor(); //invalidate(); enteranim(); } /** * 进入动画 */ public void enteranim(){ mhandlerenter.sendemptymessage(0); } /** * 退出动画 */ public void exitanim(){ mhandlerexit.sendemptymessage(0); } /** * 设置外圆动画的颜色 * @param outerpaintcolor */ public void setouterpaintcolor(int outerpaintcolor) { if (outerpaintcolor == mouterpaintcolor) { return; } mouterpaintcolor = outerpaintcolor; mouterpaint.setcolor(mouterpaintcolor); invalidate(); } /** * 设置内圆动画的颜色 * @param innerpaintcolor */ public void setinnerpaintcolor(int innerpaintcolor) { if (innerpaintcolor == minnerpaintcolor) { return; } minnerpaintcolor = innerpaintcolor; minnerpaint.setcolor(minnerpaintcolor); invalidate(); } /** * 设置图片边框的颜色 * @param bordercolor */ public void setbordercolor(int bordercolor) { if (bordercolor == mbordercolor) { return; } mbordercolor = bordercolor; mborderpaint.setcolor(mbordercolor); invalidate(); } /** * 设置图片边框的宽度 * @param borderwidth */ public void setborderwidth(int borderwidth) { if (borderwidth == mborderwidth) { return; } mborderwidth = borderwidth; setup(); } @override public scaletype getscaletype() { return scale_type; } @override public void setscaletype(scaletype scaletype) { if (scaletype != scale_type) { throw new illegalargumentexception(string.format("scaletype %s not supported.", scaletype)); } } @override protected void onsizechanged(int w, int h, int oldw, int oldh) { super.onsizechanged(w, h, oldw, oldh); //只有在此方法中调用setup,setup中的getwidth方法得到的值才不会是0, setup(); } @override public void setimagebitmap(bitmap bm) { super.setimagebitmap(bm); mbitmap = getmaxsquarecenter(bm); setup(); } /** * mxl中设置src就会走此方法 * @param drawable */ @override public void setimagedrawable(drawable drawable) { super.setimagedrawable(drawable); mbitmap = getbitmapfromdrawable(drawable); setup(); } @override public void setimageresource(int resid) { super.setimageresource(resid); mbitmap = getbitmapfromdrawable(getdrawable()); setup(); } /** * 从bitmap中间裁剪出最大的正方形 * @param bitmap * @return */ private bitmap getmaxsquarecenter(bitmap bitmap){ int w = bitmap.getwidth(); // 得到图片的宽,高 int h = bitmap.getheight(); int cropwidth = w >= h ? h : w;// 裁切后所取的正方形区域边长 return bitmap.createbitmap(bitmap, (w - cropwidth)/2 , (h - cropwidth)/2, cropwidth, cropwidth, null, false); } private bitmap getbitmapfromdrawable(drawable drawable) { if (drawable == null) { return null; } if (drawable instanceof bitmapdrawable) { //从bitmap中间裁剪出最大的正方形 bitmap bitmap = ((bitmapdrawable) drawable).getbitmap(); return getmaxsquarecenter(bitmap); //return ((bitmapdrawable) drawable).getbitmap(); } try { bitmap bitmap; if (drawable instanceof colordrawable) { bitmap = bitmap.createbitmap(colordrawable_dimension, colordrawable_dimension, bitmap_config); } else { int min = math.min(drawable.getintrinsicwidth(), drawable.getintrinsicheight()); bitmap = bitmap.createbitmap(min, min, bitmap_config); } canvas canvas = new canvas(bitmap); int left,top,right,buttom; int width = canvas.getwidth(); int height = canvas.getheight(); int abs = math.abs(width - height); if(width <= height){ left = 0; top = (height - abs) / 2; right = width; buttom = height - top; }else{ left = (width - abs) / 2; top = 0; right = width - left; buttom = height; } //drawable.setbounds(0, 0, canvas.getwidth(), canvas.getheight()); drawable.setbounds(left, top, right, buttom); drawable.draw(canvas); return bitmap; } catch (outofmemoryerror e) { return null; } } private void setup() { //只有执行过构造函数之后,所有的成员才被初始化完毕 if (!mready) { msetuppending = true; return; } if (mbitmap == null) { return; } mbitmapshader = new bitmapshader(mbitmap, shader.tilemode.clamp, shader.tilemode.clamp); mbitmappaint.setantialias(true); mbitmappaint.setshader(mbitmapshader); mborderpaint.setstyle(paint.style.stroke); mborderpaint.setantialias(true); mborderpaint.setcolor(mbordercolor); mborderpaint.setstrokewidth(mborderwidth); mbitmapheight = mbitmap.getheight(); mbitmapwidth = mbitmap.getwidth(); //图片边框设置的范围 mborderrect.set(0, 0, getwidth(), getheight()); mborderradius = math.min((mborderrect.height() - mborderwidth) / 2, (mborderrect.width() - mborderwidth) / 2) / 2; mrealborderradius = 2 * mborderradius; //图片显示的范围 mdrawablerect.set(mborderwidth, mborderwidth, mborderrect.width() - mborderwidth, mborderrect.height() - mborderwidth); //让图片显示的范围是控件大小的一半 mdrawableradius = math.min(mdrawablerect.height() / 2, mdrawablerect.width() / 2) / 2; mrealdrawableradius = 2 * mdrawableradius; updateshadermatrix(); initanimcolor(); invalidate(); } private void updateshadermatrix() { float scale; float dx = 0; float dy = 0; mshadermatrix.set(null); if (mbitmapwidth * mdrawablerect.height() > mdrawablerect.width() * mbitmapheight) { scale = mdrawablerect.height() / (float) mbitmapheight / 2; //将图片缩放在正中间 dx = (mdrawablerect.width() - mbitmapwidth * scale) * 0.5f; } else { scale = mdrawablerect.width() / (float) mbitmapwidth / 2; dy = (mdrawablerect.height() - mbitmapheight * scale) * 0.5f; } mshadermatrix.setscale(scale , scale ); mshadermatrix.posttranslate((int) (dx + 0.5f) + mborderwidth + mdrawableradius, (int) (dy + 0.5f) + mborderwidth); mbitmapshader.setlocalmatrix(mshadermatrix); } }
参考:https://github.com/hdodenhof/circleimageview
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Android实现动态圆环的图片头像控件
-
Android自定义控件:图形报表的实现(折线图、曲线图、动态曲线图)(View与SurfaceView分别实现图表控件)
-
Android编程实现GridView控件点击图片变暗效果的方法
-
android 实现APP中改变头像图片的实例代码
-
Android编程实现GridView控件点击图片变暗效果的方法
-
Android 拍照选择图片并上传功能的实现思路(包含权限动态获取)
-
Android自定义控件:图形报表的实现(折线图、曲线图、动态曲线图)(View与SurfaceView分别实现图表控件)
-
Android通过自定义ImageView控件实现图片的缩放和拖动的实现代码
-
android 实现APP中改变头像图片的实例代码
-
Android通过自定义ImageView控件实现图片的缩放和拖动的实现代码