自定義View相關總結

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

一般我們理解的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的效果同樣,兩個區域的交集。

摘自鏈接:http://blog.csdn.net/xxbs2003/article/details/9423345

五:在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

  取兩圖層所有區域,交集部分變爲透明色

六:繪製視圖時方法彙總

  /**
  *  獲得一個隨機顏色
  * @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;  }  

相關文章
相關標籤/搜索