Android ImageView绘制圆角效果
程序员文章站
2024-02-24 18:42:04
前言
android 开发中,我们经常需要实现图片的圆形/圆角的效果,我们可以使用两种方式来实现这样的效果。一种是使用xfermode,另一种是bitmapshader来...
前言
android 开发中,我们经常需要实现图片的圆形/圆角的效果,我们可以使用两种方式来实现这样的效果。一种是使用xfermode,另一种是bitmapshader来实现。下面我将分别介绍这两种用法。
使用xfermode的方式实现
使用该方式的关键代码,如下:
private bitmap creatabitmap(bitmap bitmap) { //用指定的一个bitmap来构建一个画布 bitmap target = bitmap.createbitmap(1000,1000, bitmap.config.argb_8888); canvas canvas = new canvas(target); final paint paint = new paint(); paint.setcolor(color.green); paint.setantialias(true); //在刚才的画布上绘制一个圆形区域 canvas.drawcircle(500,500,500,paint); //设置xfermode,使用src_in模式,这样可以取到第二张图片重叠后的区域 paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in)); //在画布上绘制第二个需要显示的bitmap canvas.drawbitmap(bitmap,0,0,paint); return target; }
上面代码中看出在指定的画布上绘制了两层图像,一个是半径为500像素的圆形,一个是将目标bitmap绘制在上面。之间还调用了paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in));作用是这两个绘制的效果图叠加后,取得第二个图的交集图。所以,我们先绘制一个圆形,然后绘制bitmap,交集为圆形,取出的就是圆形区域的bitmap了。
porterduff.mode中一共有16种效果显示,如下:
可以根据不同的mode,控制显示的效果图。
开始应用
1.自定义属性在attrs.xml中
<?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> <attr name="src" format="reference"/> <declare-styleable name="roundimageview"> <attr name="borderradius"/> <attr name="type"/> <attr name="src"/> </declare-styleable> </resources>
2.自定义view
public class roundimageview extends view { private int type; private static final int type_circle = 0; private static final int type_round = 1; //图片 private bitmap msrc; //圆角大小 private int mradius; //高度 private int mwidth; //宽度 private int mheight; public roundimageview(context context, attributeset attrs) { super(context, attrs); //获取自定义的属性 typedarray a = context.obtainstyledattributes(attrs,r.styleable.roundimageview); //获取自定以属性的数目 int count = a.getindexcount(); for (int i=0 ; i<count ; i++){ int attr = a.getindex(i); switch (attr){ case r.styleable.roundimageview_borderradius: int defvalue = (int) typedvalue.applydimension(typedvalue.complex_unit_dip,10f,getresources().getdisplaymetrics()); mradius = a.getdimensionpixelsize(attr, defvalue); break; case r.styleable.roundimageview_type: type = a.getint(attr,0); break; case r.styleable.roundimageview_src: msrc = bitmapfactory.decoderesource(getresources(),a.getresourceid(attr,0)); break; } } a.recycle(); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); //设置宽度 int specmode = measurespec.getmode(widthmeasurespec); int specsize = measurespec.getsize(widthmeasurespec); if (specmode == measurespec.exactly){ mwidth = specsize; }else { int desirebyimg = getpaddingleft() + getpaddingright() + msrc.getwidth(); if (specmode == measurespec.at_most)// wrap_content { mwidth = math.min(desirebyimg, specsize); } else mwidth = desirebyimg; } //设置高度 specmode = measurespec.getmode(heightmeasurespec); specsize = measurespec.getsize(heightmeasurespec); if (specmode == measurespec.exactly){ mheight = specsize; }else { int desire = getpaddingtop() + getpaddingbottom() + msrc.getheight(); if (specmode == measurespec.at_most)// wrap_content { mheight = math.min(desire, specsize); } else mheight = desire; } setmeasureddimension(mwidth,mheight); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); switch (type){ case type_circle: int min = math.min(mwidth,mheight); //从当前存在的bitmap,按一定的比例创建一个新的bitmap。 msrc = bitmap.createscaledbitmap(msrc, min, min, false); canvas.drawbitmap(createcircleimage(msrc, min), 0, 0, null); break; case type_round: msrc = bitmap.createscaledbitmap(msrc, mwidth, mheight, false); canvas.drawbitmap(createroundconerimage(msrc), 0, 0, null); break; } } /** * 绘制圆角 * @param source * @return */ private bitmap createroundconerimage(bitmap source) { final paint paint = new paint(); paint.setantialias(true); bitmap target = bitmap.createbitmap(mwidth, mheight, bitmap.config.argb_8888); canvas canvas = new canvas(target); rectf rect = new rectf(0, 0, mwidth, mheight); canvas.drawroundrect(rect, mradius, mradius, paint); paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in)); canvas.drawbitmap(source, 0, 0, paint); return target; } /** * 绘制圆形 * @param source * @param min * @return */ private bitmap createcircleimage(bitmap source, int min) { final paint paint = new paint(); paint.setantialias(true); bitmap target = bitmap.createbitmap(min, min, bitmap.config.argb_8888); canvas canvas = new canvas(target); canvas.drawcircle(min/2,min/2,min/2,paint); paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in)); canvas.drawbitmap(source, 0, 0, paint); return target; } }
3.布局文件
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:roundview="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" tools:context="mo.yumf.com.myviews.mainactivity"> <mo.yumf.com.myviews.roundimageview android:layout_width="200dp" android:layout_height="200dp" android:layout_margintop="20dp" roundview:borderradius="10dp" roundview:src="@drawable/ac_default_icon" roundview:type="round"/> <mo.yumf.com.myviews.roundimageview android:layout_width="200dp" android:layout_height="200dp" android:layout_margintop="20dp" roundview:src="@drawable/ac_default_icon" roundview:type="circle"/> </linearlayout>
上面的自定义view中,存在一个局限,那就是只能在布局中设置要加载的图片资源,不能在代码中设置图片。下面我们使用同样的方式,选择自定义imageview来实现。
public class roundimageview extends imageview { private int type; private static final int type_circle = 0; private static final int type_round = 1; //图片 private bitmap msrc; //圆角大小 private int mradius; public roundimageview(context context, attributeset attrs) { super(context, attrs); //获取自定义的属性 typedarray a = context.obtainstyledattributes(attrs,r.styleable.roundimageview); //获取自定以属性的数目 int count = a.getindexcount(); for (int i=0 ; i<count ; i++){ int attr = a.getindex(i); switch (attr){ case r.styleable.roundimageview_borderradius: int defvalue = (int) typedvalue.applydimension(typedvalue.complex_unit_dip,10f,getresources().getdisplaymetrics()); mradius = a.getdimensionpixelsize(attr, defvalue); break; case r.styleable.roundimageview_type: type = a.getint(attr,0); break; } } a.recycle(); } @override protected void ondraw(canvas canvas) { if (getdrawable() != null){ bitmap bitmap = getbitmap(getdrawable()); if (bitmap != null){ switch (type){ case type_circle: //获取imageview中的宽高,取最小值 int min = math.min(getmeasuredwidth(),getmeasuredheight()); //从当前存在的bitmap,按一定的比例创建一个新的bitmap。 msrc = bitmap.createscaledbitmap(bitmap, min, min, false); canvas.drawbitmap(createcircleimage(msrc, min), 0, 0, null); break; case type_round: msrc = bitmap.createscaledbitmap(bitmap, getmeasuredwidth(), getmeasuredheight(), false); canvas.drawbitmap(createroundconerimage(msrc), 0, 0, null); break; } } }else { super.ondraw(canvas); } } private bitmap getbitmap(drawable drawable) { if (drawable instanceof bitmapdrawable){ return ((bitmapdrawable)drawable).getbitmap(); }else if (drawable instanceof colordrawable){ rect rect = drawable.getbounds(); int width = rect.right - rect.left; int height = rect.bottom - rect.top; int color = ((colordrawable)drawable).getcolor(); bitmap bitmap = bitmap.createbitmap(width,height, bitmap.config.argb_8888); canvas canvas = new canvas(bitmap); canvas.drawargb(color.alpha(color),color.red(color), color.green(color), color.blue(color)); return bitmap; }else { return null; } } /** * 绘制圆角 * @param source * @return */ private bitmap createroundconerimage(bitmap source) { final paint paint = new paint(); paint.setantialias(true); bitmap target = bitmap.createbitmap(getmeasuredwidth(), getmeasuredheight(), bitmap.config.argb_8888); canvas canvas = new canvas(target); rectf rect = new rectf(0, 0, getmeasuredwidth(), getmeasuredheight()); canvas.drawroundrect(rect, mradius, mradius, paint); paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in)); canvas.drawbitmap(source, 0, 0, paint); return target; } /** * 绘制圆形 * @param source * @param min * @return */ private bitmap createcircleimage(bitmap source, int min) { final paint paint = new paint(); paint.setantialias(true); bitmap target = bitmap.createbitmap(min, min, bitmap.config.argb_8888); canvas canvas = new canvas(target); canvas.drawcircle(min/2,min/2,min/2,paint); paint.setxfermode(new porterduffxfermode(porterduff.mode.src_in)); canvas.drawbitmap(source, 0, 0, paint); return target; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。