一:获取要绘制的文字的宽度/长度android
方法1:
Paint pFont = new Paint();
Rect rect = new Rect();
String str = "hello";canvas
//返回包围整个字符串的最小的一个Rect区域
pFont.getTextBounds(str, 0, str.length(), rect);
strwid = rect.width();
strhei = rect.height();
方法2:
//直接返回参数字符串所占用的宽度
strwid = paintHead.measureText(str); app
二:onMeasure获取视图宽高dom
private int mWidth, mHeight;ide
@Override
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);
}spa
/**
* dp转换成px
* @param dp
* @return
*/
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
getContext().getResources().getDisplayMetrics());
}.net
三: 使用Canvas的drawTextOnPath方法实现沿着Path绘制文本orm
Android的Canvas提供了一个drawTextOnPath(String text,Path path,float hOffset,float vOffset,Paint paint)方法,该方法能够沿着Path路径绘制文本,其中text指文本内容,hOffset参数指定水平偏移、vOffset指定垂直偏移对象
四: Android Canvas Region.Op中的Clip方式blog
接下来经过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的效果同样,两个区域的交集。
摘自链接:http://blog.csdn.net/xxbs2003/article/details/9423345
五:在Drawable图片上面绘制颜色
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
取两图层所有区域,交集部分变为透明色
六:绘制视图时方法汇总
/**
* 获得一个随机颜色
* @return 随机颜色
*/
public int randomColor() {
Random random = new Random();
int red = random.nextInt(256) ;
int green = random.nextInt(256) ;
int blue = random.nextInt(256);
return Color.rgb(red, green, blue);
}
/**
* 经过透明度,算出对应颜色的浅色应当是什么效果
* @param color 颜色
* @param alpha 透明度
* @return 浅色
*/
public int getLightColor(int color,int alpha)
{
initPaint();
mPaint.setColor(color);
mPaint.setAlpha(alpha);
return mPaint.getColor();
}
/**
* 获得深色
* @param color 颜色
* @return 深色
*/
public int getDarkerColor(int color){
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[1] = hsv[1] + 0.1f;
hsv[2] = hsv[2] - 0.1f;
int darkerColor = Color.HSVToColor(hsv);
return darkerColor ;
}
/**
* 获得单个字的高度
* @param paint 画笔
* @return 高度
*/
public float getPaintFontHeight(Paint paint)
{
FontMetrics fm = paint.getFontMetrics();
return (float) Math.ceil(fm.descent - fm.ascent);
}
/**
* 获得字符串的宽度
* @param paint 画笔
* @param str 字符串
* @return 宽度
*/
public float getTextWidth(Paint paint,String str)
{
if(str.length() == 0) return 0.0f;
//float width = Math.abs(paint.measureText(str, 0, str.length()));
return paint.measureText(str, 0, str.length());
}
/**
* 绘制旋转了指定角度的文字
* @param text 文字
* @param x X坐标
* @param y y坐标
* @param paint 画笔
* @param angle 角度
*/
public void drawRotateText( String text ,
float x ,float y,float angle,
Canvas canvas,
Paint paint
){
if("" == text|| text.length() == 0 ) return;
if(angle != 0){
canvas.rotate(angle, x, y);
//canvas.drawText(text, x, y, paint);
drawText(canvas,paint,text,x,y);
canvas.rotate(-1 * angle, x, y);
}else{
//canvas.drawText(text, x, y, paint);
drawText(canvas,paint,text,x,y);
}
}
public PathEffect getDotLineStyle()
{
return( new DashPathEffect(new float[] { 2, 2, 2, 2}, 1));
}
public PathEffect getDashLineStyle()
{
//虚实线
return(new DashPathEffect(new float[] { 4, 8, 5, 10}, 1));
}
/**
* 绘制点
* @param startX 起始点X坐标
* @param startY 起始点Y坐标
* @param stopX 终止点X坐标
* @param stopY 终止点Y坐标
* @param canvas 画布
* @param paint 画笔
*/
public void drawDotLine(float startX,float startY,
float stopX,float stopY,
Canvas canvas,
Paint paint)
{
//PathEffect effects = new DashPathEffect(new float[] { 2, 2, 2, 2}, 1);
paint.setPathEffect(getDotLineStyle());
canvas.drawLine(startX, startY, stopX, stopY, paint);
paint.setPathEffect(null);
}
/**
* 绘制虚实线
* @param startX 起始点X坐标
* @param startY 起始点Y坐标
* @param stopX 终止点X坐标
* @param stopY 终止点Y坐标
* @param canvas 画布
* @param paint 画笔
*/
public void drawDashLine(float startX,float startY,
float stopX,float stopY,
Canvas canvas,
Paint paint)
{
//虚实线
//PathEffect effects = new DashPathEffect(new float[] { 4, 8, 5, 10}, 1);
paint.setPathEffect(getDashLineStyle());
canvas.drawLine(startX, startY, stopX, stopY, paint);
paint.setPathEffect(null);
}
//绘制有换行的文本 public float drawText(Canvas canvas,Paint paint,String text,float x,float y) { if(text.length() > 0 ) { if( text.indexOf("\n") > 0 ){ float height = getPaintFontHeight(paint); String[] arr = text.split("\n"); for(int i=0;i<arr.length;i++){ canvas.drawText(arr[i],x , y, paint); y += height; } }else{ canvas.drawText(text,x , y, paint); } } return y; }