圆形ImageView系列(二)-----Xfermode+ImageView
来源:互联网 发布:protobuffer java 编辑:程序博客网 时间:2024/05/29 10:49
前言
上一篇文章《 圆形ImageView系列(一)—–Xfermode+View》介绍了Xfermode,并且结合View实现了圆形ImageView,这种方式实现的思路和方法都很简单,但是使用起来总感觉少了点什么。
既然是圆形ImageView,但是原生的ImageView的很多属性却使用不了,比如scaleType等等,所以下面我们使用第二种方案。
主要原理
在ImageView的上面覆盖一个遮罩层,将这个遮罩层的中间抠掉一个圆形之后,整个ImageView看起来就能显示出圆形的效果了。
先来看看效果图。
上面那张效果图里,下面的两张图可以明显的看到有个白色的遮罩层覆盖在ImageView上面,所以看起来就显示成了圆形ImageView的效果。
具体实现
package com.passerby.androidadvanced.circleimage.imageview;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.widget.ImageView;/** * Created by mac on 16/2/3. */public class CircleLayerImageView extends ImageView { public CircleLayerImageView(Context context) { this(context, null); } public CircleLayerImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleLayerImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getMeasuredWidth(); int height = getMeasuredHeight(); //创建跟imageview相同宽高的遮罩层 int min = Math.min(width, height); Bitmap bitmapMask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvasMask = new Canvas(bitmapMask); //遮罩层颜色 int maskColor; Drawable background = getBackground(); if (background != null && background instanceof ColorDrawable) { maskColor = ((ColorDrawable) background).getColor(); } else { maskColor = Color.WHITE; } canvasMask.drawColor(maskColor); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.WHITE); canvas.saveLayer(0, 0, width, height, paint, Canvas.ALL_SAVE_FLAG); canvas.drawBitmap(bitmapMask, 0, 0, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); canvas.drawCircle(width >> 1, height >> 1, min >> 1, paint); canvas.restore(); }}
看到这么少的代码是不是吓尿了,之所以这么少是因为是直接继承的ImageView,很多工作ImageView已经帮我们完成了。
代码第34行,要记得调用父类的onDraw方法,不然imageView原本的图片没法正常显示。
第39~42行,创建了一个跟imageView相同大小的遮罩层Bitmap,新建了一个canvas并且将bitmap作为参数传进去。注意这里是新建的一个canvas,而不是直接使用onDraw里面系统传入的canvas,因为我们只需要对这个遮罩bitmap画上颜色而已,如果直接使用系统的canvas,那遮罩层的颜色就画在imageView上面而不是遮罩bitmap上面了。
第44~54行,主要设置遮罩层的颜色,这个颜色从ImageView的background属性中获取,这样就不会使遮罩层显得十分突兀,比如你可以看看上面效果图里面我做了一个actionBar的效果,将圆形ImageView的background跟外面的布局颜色设置成一样,看上去效果就非常好了。
当然为了容错,有人可能不小心将background设置成了图片或者其他drawable,这里默认就设置成白色的遮罩层颜色。
第60~68行,一共5行代码,主要用到了canvas的layer知识。了解photoshop的同学对图层的概念应该非常熟悉,包括我们常用的地图软件也有很多不同的图层,具体知识请百度,这里只需要注意canvas.saveLayer和canvas.restore要成对使用就好。
第62行,将遮罩层画在新的图层上,遮罩层将作为src。
第64行,改变画笔的xfermode模式,对照之前的表,应该选取srcOut模式。
第66行,将适当大小的圆画在遮罩层上面,结合画笔的xfermode模式,画完之后的效果相当于遮罩层被抠掉了一个圆形,位于遮罩层之下的imageview就显示成圆形的效果了。
- 圆形ImageView系列(二)-----Xfermode+ImageView
- 圆形ImageView系列(一)-----Xfermode+View
- Android圆形ImageView(二)
- Android Xfermode 实战 实现圆形、圆角图片(重写ImageView)
- 圆形imageview(RoundedImageView)
- 圆形imageview
- 圆形ImageView
- 圆形ImageView
- 圆形imageView
- 圆形ImageView
- 圆形ImageView
- 圆形ImageView
- (转)【ImageView】自定义ImageView系列(一)——简单圆形图片
- Android圆形ImageView(一)
- CircleImageView 圆形imageView(转载)
- android自定义view-打造圆形ImageView(二)
- 重写ImageView使用Xfermode遮罩实现圆角和圆形
- Android使用Xfermode图形渲染方法实现自定义圆形、圆角和椭圆ImageView
- 解决MyEclipse "Your MyEclipse subscription has expired" 提示
- ICE提纲之demo/Glacier2/callback(跨网回调)
- 引用及指针
- unlink();
- linux 添加用户、权限
- 圆形ImageView系列(二)-----Xfermode+ImageView
- 用Glacier2进行事务管理
- 浏览器缓存知识小结及应用
- 栈与队列
- 《Linux别名深层原理以及命令行重要快捷键》
- 此证书的签发者无效
- source insight c++ namespace 无法跳转解决方法
- oracle 创建表空间和用户
- Linux学习笔记(七)--文件系统管理