一:獲取要繪製的文字的寬度/長度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; }