自定义View基础:Android中的颜色和颜色混合
2017-03-23 22:26
375 查看
一.简单介绍Android中的颜色
安卓支持的颜色模式:
PS:其中字母表示通道类型,数值表示该类型用多少位二进制来描述。如ARGB8888则表示有四个通道(ARGB),每个对应的通道均用8位来描述。
注意:我们常用的是ARGB8888和ARGB4444,而在所有的安卓设备屏幕上默认的模式都是RGB565,请留意这一点。
以ARGB8888为例介绍颜色定义:
A 从ox00到oxff表示从透明到不透明。
RGB 从0x00到0xff表示颜色从浅到深。
二、Android中创建和使用颜色的方法
1.java中定义颜色
2.在xml文件中定义颜色
详解: 在以上xml文件中定义了两个颜色,红色和蓝色,是没有alpha(透明)通道的。
定义颜色以‘#’开头,后面跟十六进制的值,有如下几种定义方式:
3.在java文件中引用xml中定义的颜色:
4.在xml文件(layout或style)中引用或者创建颜色
四.颜色混合模式(Alpha通道相关)
我们前边的介绍中说明了颜色的透明度是根据Alpha通道的值来确定的,但是我们的手机屏幕并不是透明的,所以我们的界面颜色其实也可以看做不是透明的,那么我们的透明度效果是如何实现的呢,就是我们的颜色合成。
(RGB通道) 最终颜色 = 绘制的颜色 + (1 - 绘制颜色的透明度) × Canvas上的原有颜色。
Android为我们提供了用于合成的api
下面贴出来一张官网的图,原理自己理解吧,不是很清楚。
五、我们每一种模式都测试一下。
图层和合成,到底合成的是什么?这个要理解清楚,其实合成的是两个界面交叉的部分。比如一个图片上覆盖了另外一层图。那么合成处理的就是这个交叉覆盖的部分。下面有两个概念:目标图是先绘制的图,源图就是后绘制的图。
首先看一段完整的代码:
此段代码是没有使用混合模式的代码,就是绘制两个图到屏幕上。其中有一些重要的地方需要提前说明一下,canVas.saveLayer(),此方法为设置一个新的图层,因为Android系统本身就会有背景图和背景颜色,所以我们设置一个新的透明图层来处理我们的图像合成,代码最后一段还原一下就OK了,如果不这样会遇到各种各样的问题,不能正确的显示我们合成的效果。下面看一下我们没有合成效果的界面效果:
ADD模式交叉的部分相互融合高亮。
CLEAR模式清除交叉部分的图像,以及上层的图片。很多博文片面的说是清除所有,是不客观的。
DARKEN模式没看到什么效果:
DST模式只显示目标图:
DST_ATOP模式:只显示交叉部分以外的目标图
DST_IN显示目标图交叉的部分以及没有被覆盖部分的图
篇幅有限,各种模式大家可以一个一个的去实验。最后提醒一点,由于摆放的位置不同同样会产生不同的效果。网上流传的很广的一张ApiDemos/Graphics/XferModes的图,其实很好理解其中的一些模式,但是不要只看图,一定要亲自测试,否则你会理解错了它所表示的意思。
博客已经移步:chaodongyang.com
关注微信公众号获取更多资讯:
安卓支持的颜色模式:
PS:其中字母表示通道类型,数值表示该类型用多少位二进制来描述。如ARGB8888则表示有四个通道(ARGB),每个对应的通道均用8位来描述。
注意:我们常用的是ARGB8888和ARGB4444,而在所有的安卓设备屏幕上默认的模式都是RGB565,请留意这一点。
以ARGB8888为例介绍颜色定义:
A 从ox00到oxff表示从透明到不透明。
RGB 从0x00到0xff表示颜色从浅到深。
二、Android中创建和使用颜色的方法
1.java中定义颜色
int color = Color.RED; int colorARGB = Color.argb(123,50,50,50); int colorNumber = 0xaabbccdd;
2.在xml文件中定义颜色
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#3F51B5</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FF4081</color> </resources>
详解: 在以上xml文件中定义了两个颜色,红色和蓝色,是没有alpha(透明)通道的。
定义颜色以‘#’开头,后面跟十六进制的值,有如下几种定义方式:
#f00 //低精度 - 不带透明通道红色 #af00 //低精度 - 带透明通道红色 #ff0000 //高精度 - 不带透明通道红色 #aaff0000 //高精度 - 带透明通道红色
3.在java文件中引用xml中定义的颜色:
int color = getResources().getColor(R.color.mycolor); int color = getColor(R.color.myColor); //API 23 及以上支持该方法
4.在xml文件(layout或style)中引用或者创建颜色
<!--在style文件中引用--> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="colorPrimary">@color/red</item> </style>
<!--在layout文件中的引用 --> android:background="@color/red" //引用在/res/values/color.xml 中定义的颜色 android:background="#ff0000" //创建并使用颜色
四.颜色混合模式(Alpha通道相关)
我们前边的介绍中说明了颜色的透明度是根据Alpha通道的值来确定的,但是我们的手机屏幕并不是透明的,所以我们的界面颜色其实也可以看做不是透明的,那么我们的透明度效果是如何实现的呢,就是我们的颜色合成。
(RGB通道) 最终颜色 = 绘制的颜色 + (1 - 绘制颜色的透明度) × Canvas上的原有颜色。
Android为我们提供了用于合成的api
Paint.setXfermode(mXfermode);
下面贴出来一张官网的图,原理自己理解吧,不是很清楚。
五、我们每一种模式都测试一下。
图层和合成,到底合成的是什么?这个要理解清楚,其实合成的是两个界面交叉的部分。比如一个图片上覆盖了另外一层图。那么合成处理的就是这个交叉覆盖的部分。下面有两个概念:目标图是先绘制的图,源图就是后绘制的图。
首先看一段完整的代码:
package net.fitrun.mysvg; 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.graphics.RectF; import android.graphics.Xfermode; import android.view.View; /** * Created by 晁东洋 on 2017/3/23. */ public class PorterDuffXfermodeView extends View{ private Paint mPaint; private Bitmap dstBmp, srcBmp; private RectF dstRect, srcRect; private Xfermode mXfermode; private PorterDuff.Mode mPorterDuffMode = PorterDuff.Mode.ADD; public PorterDuffXfermodeView(Context context) { super(context); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG); dstBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.tu); srcBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.yangying); mXfermode = new PorterDuffXfermode(mPorterDuffMode); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //背景色设为白色,方便比较效果 canvas.drawColor(Color.WHITE); //将绘制操作保存到新的图层,因为图像合成是很昂贵的操作,将用到硬件加速,这里将图像合成的处理放到离屏缓存中进行 RectF rectF = new RectF(0,0,1000,1000); int saveCount = canvas.saveLayer(rectF, mPaint, Canvas.ALL_SAVE_FLAG); //绘制目标图 RectF DErectF = new RectF(0,0,500,500); canvas.drawBitmap(dstBmp, null, DErectF, mPaint); //设置混合模式 // mPaint.setXfermode(mXfermode); //绘制源图 RectF RSrectF = new RectF(250,250,800,800); canvas.drawBitmap(srcBmp, null, RSrectF, mPaint); //清除混合模式 mPaint.setXfermode(null); //还原画布 canvas.restoreToCount(saveCount); } }
此段代码是没有使用混合模式的代码,就是绘制两个图到屏幕上。其中有一些重要的地方需要提前说明一下,canVas.saveLayer(),此方法为设置一个新的图层,因为Android系统本身就会有背景图和背景颜色,所以我们设置一个新的透明图层来处理我们的图像合成,代码最后一段还原一下就OK了,如果不这样会遇到各种各样的问题,不能正确的显示我们合成的效果。下面看一下我们没有合成效果的界面效果:
ADD模式交叉的部分相互融合高亮。
CLEAR模式清除交叉部分的图像,以及上层的图片。很多博文片面的说是清除所有,是不客观的。
DARKEN模式没看到什么效果:
DST模式只显示目标图:
DST_ATOP模式:只显示交叉部分以外的目标图
DST_IN显示目标图交叉的部分以及没有被覆盖部分的图
篇幅有限,各种模式大家可以一个一个的去实验。最后提醒一点,由于摆放的位置不同同样会产生不同的效果。网上流传的很广的一张ApiDemos/Graphics/XferModes的图,其实很好理解其中的一些模式,但是不要只看图,一定要亲自测试,否则你会理解错了它所表示的意思。
博客已经移步:chaodongyang.com
关注微信公众号获取更多资讯:
相关文章推荐
- 0917Android基础自定义View(颜色渲染PorterDuff及Xfermode)
- Android自定义View基础(三)颜色
- Android自定义View基础(三)-颜色
- Android基础教程——在TextView中显示Html 自定义标签,获取标签属性
- Android基础教程(九)之自定义下拉菜单模式----Spinner与setDropDownViewResource的应用
- android 自定义view基础知识
- Android 绘图基础:Canvas画布——自定义View基础(绘制表盘、矩形、圆形、弧、渐变)
- Android应用插件化开发中自定义View基础插件遇到的问题
- Android学习个人笔记1-Layout界面布局-xml,java混合模式-自定义view
- Android 自定义textview 部分文字字体颜色高亮
- 0916Android基础自定义View进度条专题
- Android基础教程(九)之自定义下拉菜单模式----Spinner与setDropDownViewResource的应用
- Android基础教程(九)之自定义下拉菜单模式----Spinner与setDropDownViewResource的应用
- Android自定义View基础(1)
- android基础(一)View与六大布局之自定义(下)
- 【Android基础】textview改变一部分文字的颜色和string.xml中文字的替换
- Android-如何给View添加边框,边框颜色和线的粗细可以自定义
- android 自定义键盘 KeyboardView的key 文字颜色发虚模糊
- android 自定义View(一、基础认识)