自定义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;  }  

相关文章
相关标签/搜索