[Android 知识点] 自定义View(二)
来源:互联网 发布:激光祛痘的危害 知乎 编辑:程序博客网 时间:2024/06/03 12:40
Paint类介绍
Paint类API
- 下面就一起来学习这些用法:
setARGB(int a,int r,int g,int b);设置画笔颜色
mPaint.setARGB( 255, 35, 31, 42 );
ARGB的颜色选择可以使用这网站
setAntiAlias(boolean aa); 会平滑一些
mPaint.setAntiAlias( true );
设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
setDither(boolean dither); 颜色更精细
mPaint.setDither( true );
setMaskFilter(MaskFilter maskfilter); 实现滤镜的效果
Android包含了下面几种MaskFilter:
- BlurMaskFilter 指定了一个模糊的样式和半径来处理Paint的边缘。
EmbossMaskFilter 指定了光源的方向和环境光强度来添加浮雕效果。
[x] 需要注意的是,由于在GPU硬件加速模式下,Paint的setMaskFilter不被GPU支持,所以为了能够正常使用setMaskFilter方法,我们需要将我们要绘制的View使用软件渲染模式
//为了确保画笔的setMaskFilter能供起效,我们需要对MyView禁用掉GPU硬件加速 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){ //View从API Level 11才加入setLayerType方法 //设置myView以软件渲染模式绘图 setLayerType(View.LAYER_TYPE_SOFTWARE, null); }
BlurMaskFilter 模糊效果
new BlurMaskFilter(float radius, Blur style)
radius: 阴影的模糊半径,如上图所示,其值越大表示图形绘制出来越模糊,其值越小图形越清晰。
Blur style:
EmbossMaskFilter 浮雕效果
new EmbossMaskFilter (float[] direction, float ambient, float specular, float blurRadius)
- direction
是一个float类型的数组,表示光线的方向,是个向量,包含三个值,分别是x分量、y分量、z分量,这三个值的绝对大小并不重要,因为direction最后在真正被Android使用时会被归一化成一个单位向量,即变成长度为1的向量。direction中的坐标是在所画图形的右手坐标系中定义的,如下图所示:
ambient
表示环境光因子,float类型,取值是0到1,值越接近于0,环境光越暗,值越接近于1,环境光越亮。
specular
表示镜面反射因子,float类型,取值也是0到1。镜面反射就是模拟像镜子一样的高光反射,值越接近于0,镜面反射越强,被光照照射到的地方更容易出现很白很亮的状态,即高光效果。
blurRadius
表示模糊半径,是float类型,其值越大,模糊效果越明显。
setColorFilter(ColorFilter filter) 设置颜色过滤器
可以直接传入
- ColorMatrixColorFilter
- LightingColorFilter
- PorterDuffColorFilter
的对象作为参数
ColorMatrixColorFilter 色彩矩阵颜色过滤器
在Android中图片是以RGBA像素点的形式加载到内存中的,修改这些像素信息需要一个叫做ColorMatrix类的支持,这个类其实定义的是一个矩阵,是一个4x5的float[]类型的矩阵
ColorMatrix colorMatrix = new ColorMatrix(new float[]{ 1, 0, 0, 0, 0, // 红色向量 0, 1, 0, 0, 0, // 绿色向量 0, 0, 1, 0, 0, // 蓝色向量 0, 0, 0, 1, 0, // 透明度向量 });
其中,第一行表示的R(红色)的向量,第二行表示的G(绿色)的向量,第三行表示的B(蓝色)的向量,最后一行表示A(透明度)的向量
这个矩阵不同的位置表示的R、G、B、A值,其范围在0.0F至2.0F之间,1为保持原图的RGB值。每一行的第五列数字表示”偏移值“。
- ”偏移值“:比如:(255, 253, 251, 247)和纯白(255, 255, 255, 255)之间的偏移值(0, 2, 4, 8)我们称之为白平衡的色彩偏移
我们来看看这个矩阵是怎么计算的。其实说白了就是矩阵之间的运算乘积:
这里MyColor的RGBA值我们需要转换为[0,1]。通过这种计算我们可以将我们自己设定的颜色和矩阵的颜色进行叠加,创立一个新的颜色
// 生成色彩矩阵 ColorMatrix colorMatrix = new ColorMatrix(new float[]{ -1, 0, 0, 1, 1, 0, -1, 0, 1, 1, 0, 0, -1, 1, 1, 0, 0, 0, 1, 0, }); mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale);canvas.drawBitmap(bitmap,240,600,mPaint);
原图
效果图
LightingColorFilter (int mul, int add) 亮度过滤
mul全称是colorMultiply意为色彩倍增,而add全称是colorAdd意为色彩添加,这两个值都是16进制的色彩值0xAARRGGBB、
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置颜色过滤 mPaint.setColorFilter(new LightingColorFilter(0xFFFF00FF, 0x00000000)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale); canvas.drawBitmap(bitmap,240,600,mPaint); }
运行后你会发现绿色确实是没了但是原来偏绿的部分现在居然成了红色,当LightingColorFilter(0xFFFFFFFF,0x00000000)的时候原图是不会有任何改变的,如果我们想增加红色的值,那么LightingColorFilter(0xFFFFFFFF, 0x00XX0000)就好,其中XX取值为00至FF。
效果图
PorterDuffColorFilter(int color, PorterDuff.Mode mode)
这个构造方法也接受两个值,一个是16进制表示的颜色值这个很好理解,而另一个是PorterDuff内部类Mode中的一个常量值,这个值表示混合模式。那么什么是混合模式呢?混合混合必定是有两种东西混才行,第一种就是我们设置的color值而第二种当然就是我们画布上的元素了!也就是说将画布上的元素和我们设置的color进行混合,产生最终的效果。
- PorterDuff.Mode mode
PorterDuff.Mode为枚举类,一共有16个枚举值:
@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); // 设置颜色过滤 mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN)); Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.kale); canvas.drawBitmap(bitmap,240,600,mPaint);}
效果图
setPathEffect(PathEffect effect); 设置绘制路径的效果
效果是由它的六个子类实现:
- ComposePathEffect
- CornerPathEffect
- DashPathEffec
- DiscretePathEffect
- PathDashPathEffect
- SumPathEffect
例如
mPaint.setPathEffect(new CornerPathEffect(10));
CornerPathEffect(float radius)
将路径的转角变得圆滑
DiscretePathEffect(float segmentLength, float deviation)
绘制很多“杂点”的突出来模拟一种类似生锈铁丝的效果
new DiscretePathEffect(3.0F, 5.0F)
第一个参指定这些突出的“杂点”的密度,值越小杂点越密集;
第二个参数是“杂点”突出的大小,值越大突出的距离越大反之反之。
DashPathEffect(float[] intervals, float phase)
- 第一个参数是一个浮点型的数组,只要浮点型数组中元素个数大于等于2即可。{20, 10}的偶数参数20(注意数组下标是从0开始哦)定义了我们第一条实线的长度,而奇数参数10则表示第一条虚线的长度,如果此时数组后面不再有数据则重复第一个数以此往复循环,整条线就成了[20,10,20,10,20,10…………………………]这么一个状态。
- 第二个参数(phase)我称之为偏移值,即是奇数偶数的间隔数,可以理解为取模。
PathDashPathEffect(Path shape, float advance, float phase, PathDashPathEffect.Style style)
和DashPathEffect是类似的,但我们自己定义图形和路径虚线的样式。
- shape : 是指填充图形
- advance : 每个图形间的间距
- phase : 绘制时的偏移量
- style : Style.ROTATE、Style.MORPH和Style.TRANSLATE
Path path = new Path(); path.addCircle(0, 0, 3, Direction.CCW); PathEffect pathEffect = new PathDashPathEffect(path, 12, phase, PathDashPathEffect.Style.ROTATE);
效果图:
ComposePathEffect(PathEffect outerpe, PathEffect innerpe)
SumPathEffect(PathEffect first, PathEffect second)
ComposePathEffect和SumPathEffect都可以用来组合两种路径效果,就是把两种效果二合一。唯一不同的是组合的方式:
- ComposePathEffect会先将路径变成innerpe的效果,再去复合outerpe的路径效果,即:outerpe(innerpe(Path));
- SumPathEffect(PathEffect first, PathEffect second)则会把两种路径效果加起来再作用于路径。
PathEffect pe = new DiscretePathEffect(10, 4);PathEffect pe2 = new CornerPathEffect(4);dwShape[3].getPaint().setPathEffect( new ComposePathEffect(pe2, pe));
setXfermode(Xfermode xfermode); 设置图形重叠时的处理方式
设置图形重叠时的处理方式,如合并,取交集或并集,经常用来制作橡皮的擦除效果
- AvoidXfermode
1 AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); 2 borderPen.setXfermode(avoid)
- PixelXorXfermode
1 Xfermode xFermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);2 paint.setXfermode(xFermode);
- PorterDuffXfermode
setARGB(int a,int r,int g,int b); 设置画笔颜色
设置绘制的颜色,a代表透明度,r,g,b代表颜色值。
p.setARGB(175, 216, 216, 216);
setAlpha(int a); 设置绘制图形的透明度
mBluePaint.setAlpha(10);
setColor(int color) 设置画笔制的颜色
使用颜色值来表示,该颜色值包括透明度和RGB颜色
mBluePaint.setColor(0xff0000ff);
setShader(Shader shader); 设置图像效果
使用Shader可以绘制出渲染图像以及一些几何图形
包括了5个直接子类:
- BitmapShader 图像渲染
- ComposeShader 混合渲染
- LinearGradient 线性渲染
- RadialGradient 环形渲染
- SweepGradien 梯度渲染
BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY);
- bitmap : 表示用来作为纹理填充的位图
- Shader.TileMode
new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile);
作用是实现某一区域内颜色的线性渐变效果
- x0表示渐变的起始点x坐标
- y0表示渐变的起始点y坐标
- x1表示渐变的终点x坐标
- y1表示渐变的终点y坐标
- colors表示渐变的颜色数组
- positions用来指定颜色数组的相对位;
- tile表示平铺方式
通常,参数positions设为null,表示颜色数组以斜坡线的形式均匀分布。
另外一种构造方式:
LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
- color0表示渐变开始颜色
- color1表示渐变结束颜色
利用LinearGradient实现一个从蓝色线性渐变到红色的圆形图:
new LinearGradient(width / 2, 0, width / 2, height, 0xffffffff, 0x00ffffff,Shader.TileMode.CLAMP);
ComposeShader (Shader shaderA, Shader shaderB, PorterDuff.Mode mode);
作用是实现渲染效果的叠加,如BitmapShader与LinearGradient的混合渲染效果等
- 参数shaderA表示某一种渲染效果
- 参数shaderB也表示某一种渲染效果
- 参数mode表示两种渲染效果的叠加模式
RadialGradient (float x, float y, float radius, int[] colors, float[] positions, Shader.TileMode tile);
作用是在某一区域内实现环形的渐变效果
- 参数x表示环形的圆心x坐标
- 参数y表示环形的圆心y坐标
- 参数radius表示环形的半径
- 参数colors表示环形渐变的颜色数组
- 参数positions用来指定颜色数组的相对位置
- 参数tile表示平铺的方式
new RadialGradient(37.5f, 12.5f, 50f, color, darkColor, Shader.TileMode.CLAMP);
SweepGradient (float cx, float cy, int[] colors, float[] positions);
梯度渲染,是指在某一中心以x轴正方向逆时针旋转一周而形成的扫描效果的渲染形式。
- 参数cx表示扫描的中心x坐标;
- 参数cy表示扫描的中心y坐标;
- 参数colors表示梯度渐变的颜色数组;
- 参数positions用来指定颜色数组的相对位置。
new SweepGradient(0.0f, 0.0f, 0xff000000, 0xffffffff);
setShadowLayer(float radius ,float dx,float dy,int color); 在图形下面设置阴影层
产生阴影效果
- 第一个参数为模糊半径,越大越模糊
- 第二个参数是阴影离开文字的x横向距离
- 第三个参数是阴影离开文字的Y横向距离
- 第四个参数是阴影颜色
valuePaint.setShadowLayer(0.5f, 0, 0.5f, 0xFFFFFFFF);
setStyle(Paint.Style style); 设置画笔的样式
Paint.Style类型有
paint.setStyle(Paint.Style.STROKE);
setStrokeCap(Paint.Cap cap); 设置笔刷的图形样式
当画笔样式为STROKE或FILL_OR_STROKE时可用
- Cap.ROUND 圆形样式
- Cap.SQUARE 方形样式
setSrokeJoin(Paint.Join join); 设置绘制时各图形的结合方式
- Join.MITER(结合处为锐角)
- Join.Round(结合处为圆弧)
- Join.BEVEL(结合处为直线)
setStrokeWidth(float width); 设置笔刷的粗细度
当画笔样式为STROKE或FILL_OR_STROKE时可用
pt.setStrokeWidth(12.0f);
setFakeBoldText(boolean fakeBoldText); 模拟实现粗体文字
设置在小字体上效果会非常差
setSubpixelText(boolean subpixelText); 对文本的一种优化设置
设置自像素。如果该项为true,将有助于文本在LCD屏幕上的显示效果
setTextAlign(Paint.Align align); 设置绘制文字的对齐方向
- CENTER: 居中
- LEFT: 左对齐
- RIGHT :右对齐
setTextScaleX(float scaleX); 设置绘制文字x轴的缩放比例
可以实现文字的拉伸的效果
setTextSize(float textSize); 设置绘制文字的字号大小
setTextSkewX(float skewX); 设置斜体文
- skewX为倾斜弧度
setTypeface(Typeface typeface); 字体风格
- Typeface.DEFAULT:默认字体。
- Typeface.DEFAULT_BOLD:加粗字体。
- Typeface.MONOSPACE:monospace字体。
- Typeface.SANS_SERIF:sans字体。
- Typeface.SERIF:serif字体。
/将字体文件保存在assets/fonts/目录下,创建Typeface对象Typeface typeFace =Typeface.createFromAsset(getAssets(),"fonts/HandmadeTypewriter.ttf");//使用字体textView.setTypeface(typeFace);
setUnderlineText(boolean underlineText); 设置带有下划线的文字效果
setStrikeThruText(boolean strikeThruText); 设置带有删除线的效果
setLetterSpacing(float letterSpacing) 设置行的间距
默认值是0,负值行间距会收缩
setFontFeatureSettings(String settings) 设置字体样式,可以设置CSS样式
measureText(char[] text, int index, int count) 测量字体的长度
measureText(String text, int start, int end)
measureText(String text)
measureText(CharSequence text, int start, int end)
paint.measureText(mString);
breakText(char[] text, int index, int count,float maxWidth, float[] measuredWidth) 截取指定长度的显示
breakText(CharSequence text, int start, int end,boolean measureForwards, floatmaxWidth, float[] measuredWidth)
breakText(String text, boolean measureForwards,float maxWidth, float[] measuredWidth)
剪切显示,就是大于maxWidth的时候只截取指定长度的显示
p.breakText(text, true, maxSize - 12, null);
getTextWidths(char[] text, int index, int count,float[] widths) 提取指定范围内的字符串
getTextWidths(CharSequence text, int start, int end, float[] widths)
getTextWidths(String text, int start, int end, float[] widths)
getTextWidths(String text, float[] widths)
提取指定范围内的字符串,保存到widths中
mScalePaint.getTextWidths("...", 0, 1, widths);
getTextPath(char[] text, int index, int count, float x, float y, Path path) 获取文本绘制的路径
getTextPath(String text, int start, int end, float x, float y, Path path)
获取文本绘制的路径,提取到Path中
mHugePaint.getTextPath(text, 0, count, 0, 0, path);
getTextBounds(String text, int start, int end, Rect bounds) 得到文本的边界
getTextBounds(char[] text, int index, int count, Rect bounds)
得到文本的边界,上下左右,提取到bounds中,可以通过这计算文本的宽和高
mTextPaint.getTextBounds( mLabel, 0, mLabel.length(), mBounds );
文本FontMetrics类:
textPaint.getFontMetrics();
基准点是baseline
- ascent:是baseline之上至字符最高处的距离
- descent:是baseline之下至字符最低处的距离
- leading:是上一行字符的descent到下一行的ascent之间的距离,也就是相邻行间的空白距离
- top:是指的是最高字符到baseline的值,即ascent的最大值
- bottom:是指最低字符到baseline的值,即descent的最大值
ascent() + descent() 可以看成文字的height。
mPaint.measureText(text) 可以看成文字的width。
绘画文字时候的x,y坐标为:
dx = (int) mPaint.measureText(String.valueOf(mDayOfMonth)) / 2;dy = (int) (-mPaint.ascent() + mPaint.descent()) / 2;
- [Android 知识点] 自定义View(二)
- android 自定义View知识点
- [Android 知识点] 自定义View(一)
- [Android 知识点] 自定义View(三)
- Android 自定义View (二)
- Android 自定义View (二)
- Android 自定义View (二)
- Android 自定义View (二)
- android 自定义view二
- Android自定义View(二)
- Android 自定义View 二
- Android 自定义View (二) 进阶
- Android 自定义View (二) 进阶
- Android 自定义View (二) 进阶
- Android 自定义View (二) 进阶
- android自定义View(二)
- Android 自定义View (二) 进阶
- Android 自定义View (二) 进阶
- HP存储raid5两块硬盘离线lvm下vxfs文件系统恢复数据方案
- 关于分布式系统的数据一致性问题(四)
- javaScript中escape()、unescape()、encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()
- BootStrap,layUi等等前端框架,前端插件,模板页
- Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use.
- [Android 知识点] 自定义View(二)
- struts2+spring+mybatis
- vim强大探究之光标移动
- 欢迎使用CSDN-markdown编辑器
- mybatis-generator最详细的配置详解
- LeetCode 10 Regular Expression Matching
- DEDECMS首页自动生成静态文件index.html
- 【Leetcode】119. Pascal's Triangle II
- 发送邮件