作者:林振萍俊諭 | 来源:互联网 | 2023-09-10 12:48
两种方法实现CircleImageView1、使用BitmapShader:BitmapShader是Paint的5个渲染器之一,通过setShader(Shade
两种方法实现CircleImageView 1、使用BitmapShader : BitmapShader是Paint的5个渲染器之一,通过setShader (Shader shader)方法设置给Paint对象 我们看看BitmapShader的构造方法: public BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY) 在安卓api中这样解释道:
Call this to create a new shader that will draw with a bitmap.
说明这个BitmapShader是使用构造器中的bitmap作为内容,渲染效果就是paint对象画过的区域变为bitmap的对应区域 ,你可以想想小时候那种笔写字了看不到,要用紫光还是什么光照到才可以看到那种效果,不过这里可以理解为,照到了就不会消失的,因为紫光(paint)走过了 这个我仅仅复制粘贴
static final Shader.TileMode CLAMP: 边缘拉伸. static final Shader.TileMode MIRROR:在水平方向和垂直方向交替景象, 两个相邻图像间没有缝隙. Static final Shader.TillMode REPETA:在水平方向和垂直方向重复摆放,两个相邻图像间有缝隙缝隙.
下面是代码: import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.BitmapShader;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Shader;import android.util.AttributeSet;import android.widget.ImageView;import com.xxhui.circleiamgeviewdemo.R;/*** Created by xxhui on 2016/8/6.* 这个是通过bitmapShader实现*/ public class CircleImageViewByBitmapShader extends ImageView {private int width;private int height;private int radius;public CircleImageViewByBitmapShader (Context context) {super (context);}public CircleImageViewByBitmapShader (Context context, AttributeSet attrs) {super (context, attrs);}@Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {super .onSizeChanged(w, h, oldw, oldh);width = w;height = h;radius = Math.min(width, height) / 2 ;}@Override protected void onDraw (Canvas canvas) {canvas.drawColor(Color.GREEN);Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.photo);BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);Paint paint = new Paint();paint.setAntiAlias(true );paint.setShader(bitmapShader);canvas.drawCircle(width / 2 , height / 2 , radius, paint);} }
2、使用Xfermode 这个主角还是paint
我们通过setXfermode给paint设置一个Xfermode 这里用到一个类PorterDuffXfermode 这里来看看构造方法如何 public PorterDuffXfermode (PorterDuff.Mode mode) 那么我们就要了解一下PorterDuff.Mode,这里要了解两个基本的就是SRC和DST因为其他看意思就能推测出来啦,DST先画的部分,SRC后画的部分,听说常用的是DET_IN 和SRC_IN,我们看图解释一下这两个,其他也是差不多或者看图理解一下。 SRC_IN:因为是in,两个图形取交集,只 取得到SRC(后画)的部分 DET_IN:取交集,只 取得到DET(先画)的部分 说完基本知识了,这里说说我的,基本思路(思路肯定很多的,自己实践的时候是什么就什么吧)我这里我用到了SRC_IN,这就涉及到取交集了,先用一个canvas,先画 一个圆,后画 整张bitmap,取交集,得到bitmap的后画 部分,想想是不是圆形的bitmap? 得到了圆形的bitmap了,这个要真正放到ondraw方法的canvas上面,毕竟哪个canvas才是要显示的,哈哈哈,就到这里啦,上代码,看看设置Xfernode的时机! import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.util.AttributeSet;import android.widget.ImageView;import com.xxhui.circleiamgeviewdemo.R;/*** Created by xxhui on 2016/8/6.*/ public class CircleImageViewByXfermode extends ImageView {private int width;private int height;private int radius;public CircleImageViewByXfermode (Context context) {super (context);}public CircleImageViewByXfermode (Context context, AttributeSet attrs) {super (context, attrs);}@Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {super .onSizeChanged(w, h, oldw, oldh);width = w;height = h;radius = Math.min(width, height) / 2 ;}@Override protected void onDraw (Canvas canvas) {super .onDraw(canvas);canvas.drawColor(Color.BLUE);Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.photo);Bitmap out = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas1 = new Canvas(out);Paint paint = new Paint();paint.setAntiAlias(true );canvas1.drawCircle(width/2 ,height/2 ,radius,paint);paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));canvas1.drawBitmap(bitmap,0 ,0 ,paint);canvas.drawBitmap(out,0 ,0 ,null );} }
其实放入时机就是先画和后画中间
效果图: