canvas教程

自定义View相关总结

字号+ 作者:H5之家 来源:H5之家 2017-09-09 16:04 我要评论( )

自定义View相关总结

目录


一、获取要绘制的文字的宽度/长度
二、onMeasure获取视图宽高
三、使用Canvas的drawTextOnPath方法实现沿着Path绘制文本
四、Android Canvas Region.Op中的Clip方式
五、在Drawable图片上面绘制颜色

一:获取要绘制的文字的宽度/长度


方法1:
Paint pFont = new Paint();
Rect rect = new Rect();
String str = "hello";
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds(str, 0, str.length(), rect);
strwid = rect.width();
strhei = rect.height();
方法2:
//直接返回参数字符串所占用的宽度
strwid = paintHead.measureText(str);

二:onMeasure获取视图宽高


private int mWidth, mHeight;
[@Override](https://my.oschina.net/u/1162528)
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthSpecMode == MeasureSpec.EXACTLY
|| widthSpecMode == MeasureSpec.AT_MOST) {
mWidth = widthSpecSize;
} else {
mWidth = 0;
}
if (heightSpecMode == MeasureSpec.AT_MOST
|| heightSpecMode == MeasureSpec.UNSPECIFIED) {
mHeight = dipToPx(15);
} else {
mHeight = heightSpecSize;
}
setMeasuredDimension(mWidth, mHeight);
}
/**
* dp转换成px
* [@param](https://my.oschina.net/u/2303379) dp
* [@return](https://my.oschina.net/u/556800)
*/
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getContext().getResources().getDisplayMetrics());
}

三: 使用Canvas的drawTextOnPath方法实现沿着Path绘制文本


Android的Canvas提供了一个drawTextOnPath(String text,Path path,float hOffset,float vOffset,Paint paint)方法,该方法可以沿着Path路径绘制文本,其中text指文本内容,hOffset参数指定水平偏移、vOffset指定垂直偏移


四: Android Canvas Region.Op中的Clip方式


通常咱们理解的clip(剪切),是对已经存在的图形进行clip的。但是,在android上是对canvas(画布)上进行clip的,要在画图之前对canvas进行clip,如果画图之后再对canvas进行clip不会影响到已经画好的图形。一定要记住clip是针对canvas而非图形。


接下来通过android自带的APIdemo Clipping例子详细讲述Clip中的Op的参数的意思。Android提供clipRect、clipPath和clipRegion剪切区域的API。


Op一共有 DIFFERENCE,INTERSECT,UNION,XOR, REVERSE_DIFFERENCE, REPLACE六种选择。



例子:


在canvas上剪切从(0,0)到(60,60)的方块。下图蓝色区域加紫色区域。


在canvas上剪切从(40,40)到(100,100)的方块。下图橄榄色区域加紫色区域。


在canvas上剪切从(0,0)到(100,100)的方块。




先在第二方块上加上Op参数例如:canvas.clipRect(40, 40, 100, 100, Region.Op. DIFFERENCE);


首先,需要搞清楚Op参数针对的对象。接着了解其含义。


Op参数针对的对象是之前剪切的区域以及当前要剪切的区域。


在本例中涉及到区域是从(0,0)到(60,60)的方块和从(40,40)到(100,100)的方块。


那有哪些含义呢?就是表示当前要剪切的区域与之前剪切过的之间的关系。



DIFFERENCE:之前剪切过除去当前要剪切的区域(蓝色区域)。


INTERSECT:当前要剪切的区域在之前剪切过内部的部分(紫色区域)----->即求交集。


UNION:当前要剪切的区域加上之前剪切过内部的部分(蓝色区域+紫色区域+橄榄色区域)----->即求并集。


XOR:异或,当前要剪切的区域与之前剪切过的进行异或。(蓝色区域+橄榄色区域)----->即除去交集部分。


REVERSE_DIFFERENCE:与DIFFERENCE相反,以当前要剪切的区域为参照物,当前要剪切的区域除去之前剪切过的区域(橄榄色区域);


REPLACE:用当前要剪切的区域代替之前剪切过的区域。(橄榄色区域+紫色区域)----->即完全替代,相当于重绘;


没带Op参数效果与INTERSECT的效果一样,两个区域的交集。


摘自连接:


五:在Drawable图片上面绘制颜色


[@Override]
protected void onDraw(Canvas canvas) {
Drawable mDrawable = context.getResources().getDrawable(R.drawable.btn_default_normal);
mDrawable.setBounds(0, 0, 150, 48);
mDrawable.setDither(true);
ColorFilter filter = new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY); //下面有讲解
mDrawable.setColorFilter(filter);
mDrawable.draw(canvas);
}

颜色渲染:PorterDuff.Mode详解


PorterDuff:



首先看一下效果图(来自ApiDemos/Graphics/XferModes)



从上面我们可以看到PorterDuff.Mode为枚举类,一共有16个枚举值:


1.PorterDuff.Mode.CLEAR 所绘制不会提交到画布上。


2.PorterDuff.Mode.SRC 显示上层绘制图片


3.PorterDuff.Mode.DST 显示下层绘制图片


4.PorterDuff.Mode.SRC_OVER 正常绘制显示,上下层绘制叠盖。


5.PorterDuff.Mode.DST_OVER 上下层都显示。下层居上显示。


6.PorterDuff.Mode.SRC_IN 取两层绘制交集。显示上层。


7.PorterDuff.Mode.DST_IN 取两层绘制交集。显示下层。


8.PorterDuff.Mode.SRC_OUT 取上层绘制非交集部分。


9.PorterDuff.Mode.DST_OUT 取下层绘制非交集部分。


10.PorterDuff.Mode.SRC_ATOP 取下层非交集部分与上层交集部分


11.PorterDuff.Mode.DST_ATOP 取上层非交集部分与下层交集部分


12.PorterDuff.Mode.XOR 异或:去除两图层交集部分


13.PorterDuff.Mode.DARKEN 取两图层全部区域,交集部分颜色加深


14.PorterDuff.Mode.LIGHTEN 取两图层全部,点亮交集部分颜色


15.PorterDuff.Mode.MULTIPLY 取两图层交集部分叠加后颜色


16.PorterDuff.Mode.SCREEN 取两图层全部区域,交集部分变为透明色


 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Android TextView 去掉自适应默认的fontpadding的实现方法

    Android TextView 去掉自适应默认的fontpadding的实现方法

    2017-09-09 11:00

  • 公共技术点( View 绘制流程)

    公共技术点( View 绘制流程)

    2017-09-07 15:03

  • 前奏:自定义View(一)onDraw()中一些常用的属性和方法总结

    前奏:自定义View(一)onDraw()中一些常用的属性和方法总结

    2017-08-31 11:08

  • SurfaceView 典型用法

    SurfaceView 典型用法

    2017-08-30 10:03

网友点评
<