Android自定义View——可在背景图和前景图显示遮罩效果的ImageView
来源:互联网 发布:mysql 连接远程数据库 编辑:程序博客网 时间:2024/04/30 06:59
如果对android自定义view还不太属性,可以查看我之前写的文章《Android自定义View——基础知识篇》
废话不多说,先上效果图
从图中可以看出,我们可以设置背景图或前景图的遮罩,而且遮罩范围可以设置为整张图片或非透明部分,另外,还可以设置遮罩的颜色。
实现的难点在于,遮罩范围可以设置为整张图片或非透明部分:
1.遮罩范围为整张图片时,直接通过canvas.drawColor(),在图片上面绘制一层遮罩。
2.遮罩为非透明部分时,则通过drawable.setColorFilter(),设置drawable对象的颜色滤镜。原理如下:
// 创建新的颜色矩阵 ColorMatrix colorMatrix = new ColorMatrix(new float[]{ a,b,c,d,e, f,g,h,i,j, k,l,m,n,o, p,q,r,s,t}); // 已知一个颜色值ARGB,则经过下面的矩阵运算可得出新的颜色值 /* int red = a*R + b*R + c*R + d*R + e; int green = f*G + g*G + h*G + i*G + j; int blue = k*B + l*B + m*B + n*B + o; int alpha = p*A + q*A + r*A + s*A + t; */ // 设置图片滤镜 getDrawable().setColorFilter(new ColorMatrixColorFilter(colorMatrix)); 绘图 drawable.draw(canvas)
(要更深入了解图像颜色处理,可以查看这篇文章:http://www.cnblogs.com/menlsh/archive/2013/02/03/2890888.html)
关键代码:
/** * 可在背景图和前景图显示遮罩效果的ImageView (前提设置了setClickable(true)) * * @author huangziwei * */public class MaskImageView extends ImageView { // 遮罩的范围 public static final int MASK_LEVEL_BACKGROUND = 1; // 背景图显示遮罩 public static final int MASK_LEVEL_FOREGROUND = 2; // 前景图显示遮罩 private boolean mIsIgnoreAlpha = true; // 是否忽略图片的透明度,默认为true,透明部分不显示遮罩 private boolean mIsShowMaskOnClick = true; // 点击时是否显示遮罩,默认开启 private int mShadeColor = 0x00ffffff; // 遮罩颜色(argb,需要设置透明度) private int mMaskLevel = MASK_LEVEL_FOREGROUND; // 默认为前景图显示遮罩 ColorMatrix mColorMatrix = new ColorMatrix(); // 颜色矩阵 ColorFilter mColorFilter; public MaskImageView(Context context) { this(context, null); } public MaskImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MaskImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MaskImageView); mIsIgnoreAlpha = a.getBoolean(R.styleable.MaskImageView_is_ignore_alpha, mIsIgnoreAlpha); mIsShowMaskOnClick = a.getBoolean(R.styleable.MaskImageView_is_show_mask_on_click, mIsShowMaskOnClick); mShadeColor = a.getColor(R.styleable.MaskImageView_mask_color, mShadeColor); mMaskLevel = a.getInt(R.styleable.MaskImageView_mask_level, mMaskLevel); // 忽略透明度时的颜色矩阵 float r = Color.alpha(mShadeColor) / 255f; r=r-(1 - r)*0.15f; float rr = (1 - r)*1.15f; setColorMatrix(new float[]{ rr, 0, 0, 0, Color.red(mShadeColor) * r, 0, rr, 0, 0, Color.green(mShadeColor) * r, 0, 0, rr, 0, Color.blue(mShadeColor) * r, 0, 0, 0, 1, 0, }); a.recycle(); } private void setColorMatrix(float[] matrix) { mColorMatrix.set(matrix); mColorFilter = new ColorMatrixColorFilter(mColorMatrix); } // all drawables instances loaded from the same resource share a common state // 从同一个资源文件获取的drawable对象共享一个状态信息,为了避免修改其中一个drawable导致其他drawable被影响,需要调用mutate() // 因为背景图在draw()阶段绘制,所以修改了背景图状态后必须调用invalidateSelf()刷新 private void setDrawableColorFilter(ColorFilter colorFilter) { if (mMaskLevel == MASK_LEVEL_BACKGROUND) { if (getBackground() != null) { getBackground().mutate(); getBackground().setColorFilter(colorFilter); getBackground().invalidateSelf(); } } else if (mMaskLevel == MASK_LEVEL_FOREGROUND) { if (getDrawable() != null) { getDrawable().mutate(); getDrawable().setColorFilter(colorFilter); getDrawable().invalidateSelf(); } } } @Override protected void onDraw(Canvas canvas) { if (mIsIgnoreAlpha) { // 忽略透明度 if (mIsShowMaskOnClick && isPressed()) { // 绘制遮罩层 setDrawableColorFilter(mColorFilter); } else { setDrawableColorFilter(null); } super.onDraw(canvas); } else { // 不忽略透明度 setDrawableColorFilter(null); if (mMaskLevel == MASK_LEVEL_BACKGROUND) { // 背景图 if (mIsShowMaskOnClick && isPressed()) { // 绘制遮罩层 canvas.drawColor(mShadeColor); } super.onDraw(canvas); } else { // 前景图 super.onDraw(canvas); if (mIsShowMaskOnClick && isPressed()) { // 绘制遮罩层 canvas.drawColor(mShadeColor); } } } } /** * view状态改变 */ @Override protected void drawableStateChanged(){ super.drawableStateChanged(); invalidate(); } public boolean isIsIgnoreAlpha() { return mIsIgnoreAlpha; } public void setIsIgnoreAlpha(boolean mIsIgnoreAlpha) { this.mIsIgnoreAlpha = mIsIgnoreAlpha; invalidate(); } public boolean isIsShowMaskOnClick() { return mIsShowMaskOnClick; } public void setIsShowMaskOnClick(boolean mIsShowMaskOnClick) { this.mIsShowMaskOnClick = mIsShowMaskOnClick; invalidate(); } public int getShadeColor() { return mShadeColor; } public void setShadeColor(int mShadeColor) { this.mShadeColor = mShadeColor; // 忽略透明度时的颜色矩阵 float r = Color.alpha(mShadeColor) / 255f; r=r-(1 - r)*0.15f; float rr = (1 - r)*1.15f; setColorMatrix(new float[]{ rr, 0, 0, 0, Color.red(mShadeColor) * r, 0, rr, 0, 0, Color.green(mShadeColor) * r, 0, 0, rr, 0, Color.blue(mShadeColor) * r, 0, 0, 0, 1, 0, }); invalidate(); } public int getMaskLevel() { return mMaskLevel; } public void setMaskLevel(int mMaskLevel) { this.mMaskLevel = mMaskLevel; invalidate(); }}
// res/values/attrs.xml<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MaskImageView"> <attr name="mask_level" format="enum"> <enum name="background" value="1"/> <enum name="foreground" value="2"/> </attr> <!-- 设置了setClickable(true)才生效,默认开启遮罩--> <attr name="is_show_mask_on_click" format="boolean"/> <attr name="mask_color" format="color"/> <!--是否忽略图片的透明度,默认为true,透明部分不显示遮罩 --> <attr name="is_ignore_alpha" format="boolean"/> </declare-styleable></resources>
0 0
- Android自定义View——可在背景图和前景图显示遮罩效果的ImageView
- android自定义view实现可自由放大缩小和移动的imageView
- Android自定义View——可设置形状(圆形、圆角矩形、椭圆)的ImageView,抗锯齿
- Android自定义View——从零开始实现可暂停的旋转动画效果
- 动态设置Button、ImageView等组件在不同状态下的背景/前景显示效果。 扩展下的话可以前景/背景的显示效果可以使用网络图片。
- android自定义控件:可旋转View:可作为ImageView、ImageButton
- android自定义控件:可旋转View:可作为ImageView、ImageButton
- 获取imageView的图和背景图
- Android 自定义View (ImageView )
- Android自定义View 一个可设置四个顶点弧度的ImageView
- Android UI - 带白边的自定义ImageView效果
- Android自定义点击效果的ImageView
- Android 自定义Imageview的点击效果
- Android——自定义View loading效果
- Android自定义View——刮刮卡效果
- Android简单自定义View——获取图片颜色的ImageView
- 可滚动显示图片的 ImageView —— PanningImageView
- android imageview自定义可缩放
- updatepanel中使用alert弹出框方法(两种)
- 一道有趣的编程题
- ANSYS 17.0下载 64位 附安装教程
- 记又一次面试失败的经历
- APC注入
- Android自定义View——可在背景图和前景图显示遮罩效果的ImageView
- mysql主从复制(超简单)
- Android开发者网址导航
- union+join
- FPGA 闪烁LED
- mysql 添加外键
- iOS-CGRect、CGSize、CGPoint__UIEdgeInsets 介绍
- AS3 多线程
- 安装python包