热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

简单实现圆形ImageView

两种方法实现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);}@Overrideprotected 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;}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(Color.GREEN);//设置画布背景方便观察Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.photo);//夹在要画的图片,这里从资源文件,从其他地方也是可以的,比如sd卡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);//这里画一个实心圆,就是将实心圆大小的渲染器图片用画笔画在画布上,说的好抽象,自己加自己理解吧,这是我的理解//canvas.drawRect(0,0,width,height,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);}@Overrideprotected 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;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.BLUE);//设置画布背景方便观察Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.photo);//夹在要画的图片,这里从资源文件,从其他地方也是可以的,比如sd卡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);//画一个圆,辅助作用,应为这是先画的!//canvas1.drawCircle(0,0,radius,paint);//这个注视你可以尝试去掉,去掉你会发现,这是取先画的全部操作的并集,此时辅助区域变为这个并集paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//DST先画,SRC后画,SRC_IN是取并集中属于后画的(有点拗口自己理解)canvas1.drawBitmap(bitmap,0,0,paint);//从这可以看出,先画(圆)和后画(bitmap)的交集为圆,而刚好圆属于整合bitmap,此时只画圆部分的bitmap,而不是整个bitmapcanvas.drawBitmap(out,0,0,null);//最后只是简单的将一个为圆的bitmap画上去而已//canvas.drawBitmap(out,0,0,new Paint());//这个可以发现,其实只要不是带有Xfermode的画笔就可以了}
}

其实放入时机就是先画和后画中间

效果图:
这里写图片描述


推荐阅读
author-avatar
林振萍俊諭
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有