android Paint基本用法

一、绘制点

  Paint pointPoint = new Paint();
  pontPoint.setAntiAlias(ture);
  pontPoint.setStrokeWidth(lineWidth);
  pontPoint.setStyle(Paint.Style.STROKE);

◆ 用Canvas绘制位的的情况。在用Canvas绘制位图时,一般地,我们使用drawBitmap函数家族,在这些函数中,都有一个Paint参数,要 做到防止锯齿,我们就要使用到这个参数。如下:首先在你的构造函数中,需要创建一个Paint。
Paint mPaint = new Paint();
然后,您需要设置两个参数:
1)mPaint.setAntiAlias();
2)mPaint.setBitmapFilter(true)。第一个函数是用来防止边缘的锯齿,第二个函数是用来对位图进行滤波处理。最后,在画图的 时候,调用drawBitmap函数,只需要将整个Paint传入即可。

private void drawPoint(Canvas canvas) {
    int height = getHeight() - textSize * 4;
    int x = getWidth() / 2;
    int y = (int) (height - height * (temperatureDay - minTemp) * 1.0f / (maxTemp - minTemp)) + textSize * 2;
    int x2 = getWidth() / 2;
    int y2 = (int) (height - height * (temperatureNight - minTemp) * 1.0f / (maxTemp - minTemp)) + textSize * 2;
    xPointDay = x;
    yPointDay = y;
    xPointNight = x2;
    yPointNight = y2;
    mWidth = getWidth();
    canvas.drawCircle(x, y, radius, pointPaint);
    canvas.drawCircle(x2, y2, radius, pointPaint);
}

drawCircle功能说明
该方法用于在画布上绘制圆形,通过指定圆形圆心的坐标和半径来实现。该方法是绘制圆形的主要方法,同时也可以通过设置画笔的空心效果来绘制空心的圆形。
基本语法
public void drawCircle (float cx, float cy, float radius, Paint paint)
参数说明
cx:圆心的x坐标。
cy:圆心的y坐标。
radius:圆的半径。
paint:绘制时所使用的画笔

二、绘制文本

private void drawText(Canvas canvas) {
    int height = getHeight() - textSize * 4;
    int yDay = (int) (height - height * (temperatureDay - minTemp) * 1.0f / (maxTemp - minTemp)) + textSize * 2;
    int yNight = (int) (height - height * (temperatureNight - minTemp) * 1.0f / (maxTemp - minTemp)) + textSize * 2;
    String dayTemp = temperatureDay + "°";
    String nightTemp = temperatureNight + "°";
    float widDay = textPaint.measureText(dayTemp);
    float widNight = textPaint.measureText(nightTemp);
    float hei = textPaint.descent() - textPaint.ascent();
    canvas.drawText(dayTemp, getWidth() / 2 - widDay / 2, yDay - radius - hei / 2, textPaint);
    canvas.drawText(nightTemp, getWidth() / 2 - widNight / 2, yNight + radius + hei, textPaint);
}
  1. 在使用Canvas绘制文字时,Paint类内给了两个方法,measureText(),getTextBound();计算字符串的长度。
  2. android中文本绘制基本概念:


    image.png

    baseline是基线,在Android中绘制文本都是从baseline处开始的,从baseline往上至至文本最高处的距离称之为ascent(上坡度),baseline至文本最低处的距离称之为descent(下坡度)。
    top和bottom是绘制文本时在最外层留出的一些内边距。
    baseline是基线,baseline以上是负值,baseline以下是正值,因此ascent和top都是负值,descent和bottom都是正值。

文本的实际高度应该就是descent-asscent,但是一般都是以top-bottom作为文本的高度。
ascent,descent,top,bottom都是文本内容的属性,也即字内容的属性,这些属性都是FontMetrics这个类中的属性,FontMetrics对象可以通过Paint画笔对象mPaint.getFontMetrics()方法来获取,但是要是在paint.setTextSize(mTextSize)之后获取。
获取到Paint的FontMetrics对象之后,就可以获取到ascent,descent,top,bottom这些属性值了。

Android中绘制文本:
drawText(String text, float x, float y,Paint paint)
这里的x参数是绘制的文本的最左边的横坐标,y是baseline的纵坐标,注意这里的y不是绘制文本的纵坐标,而是baseline的纵坐标。

我们经常地一个需求就是在View的中心处绘制文本,那么以前看到网上看到最多的在View的中心处绘制文本的公式:
x=控件的宽度/2-文本的宽度/2
y=控件的高度/2+文本的高度/2
都是把y当作是绘制文本的纵坐标,其实这是不正确的,这种公式绘制出的文本并不是居中的。因为y参数并不是绘制文本的纵坐标,而是baseline的纵坐标。
那么这里根据上面的ascent,descent,top,bottom概念的学习,给出在View中心处绘制文的x,y值的计算公式:
x=getWidth()/2-mPaint.measureText(mText)/2;
y=getHeight()/2+(fontMetrics.bottom-fontMetrics.top)/2-fontMetrics.bottom

getWidth(): 控件的宽度(view的宽度)
getHeight():控件的高度(view的高度)
mPaint.measureText(mText)是精确的测出绘制文本的宽度
fontMetrics.bottom-fontMetrics.top就是绘制文本的高度。
y计算出来就是baseline的纵坐标

三、Paint其他常用属性:
1、绘制paint线帽

private void drawStrokeCap( Canvas canvas ) {
 Paint paint = new Paint();

paint.setAntiAlias( true );
paint.setStrokeWidth( 100 );
paint.setColor(Color.parseColor("#00ff00") );
paint.setStrokeCap( Paint.Cap.BUTT );       // 线帽,即画的线条两端是否带有圆角,butt,无圆角
canvas.drawLine( 100,100,400, 100, paint );

paint.setColor(Color.parseColor("#ff0000") );
paint.setStrokeCap( Paint.Cap.ROUND );       // 线帽,即画的线条两端是否带有圆角,ROUND,圆角
canvas.drawLine( 100,300,400, 300, paint );

paint.setColor(Color.parseColor("#0000ff") );
paint.setStrokeCap( Paint.Cap.SQUARE );       // 线帽,即画的线条两端是否带有圆角,SQUARE,矩形
canvas.drawLine( 100,600,400, 600, paint );
}

2、Paint与Path接合,多线条连接拐角弧度,StrokeJoin

private void drawStrokeJoin( Canvas canvas ) {
Paint paint = new Paint();

paint.setAntiAlias( true );
paint.setStrokeWidth( 20 );
paint.setStyle(Paint.Style.STROKE ); // 默认是填充 Paint.Style.FILL
paint.setColor( Color.parseColor("#0000ff") );

Path path = new Path();
path.moveTo( 100, 100 ); // 路径path默认是在原点(0,0),当前移植到(100,100)
path.lineTo( 400, 100 );
path.lineTo( 200, 200 );
paint.setStrokeJoin(Paint.Join.BEVEL );

canvas.drawPath( path, paint );

paint.setStyle(Paint.Style.STROKE );
path.moveTo( 100, 300 ); // 路径path默认是在原点(0,0),当前移植到(100,300)
path.lineTo( 500, 300 );
path.lineTo( 100, 500 );
paint.setStrokeJoin(Paint.Join.ROUND );

canvas.drawPath( path, paint );
}

3、利用path绘制简单的路径

private void drawMutilCornerPathEffect( Canvas canvas ) {
Paint paint = new Paint();
paint.setStrokeWidth( 3 );
paint.setColor( Color.RED );
paint.setStyle(Paint.Style.STROKE );
paint.setAntiAlias( true );

Path path = getPath();
canvas.drawPath( path, paint );
// canvas.save(); // 保存上一次绘制(画布),保证下一次绘制不受影响

paint.setPathEffect( new CornerPathEffect(10) );
canvas.translate( 0,300 );
canvas.drawPath( path, paint );

}

private Path getPath() {
Path path = new Path();
path.moveTo(0,0);
for( int i = 1; i <= 50; i++ ) {
    path.lineTo( 20 * i, (float) (( Math.random() * 50 * i) % 200));
}
return path;
}

4、DashPathEffect虚线的简单绘制

private void drawDashPathEffect( Canvas canvas ) {
Paint paint = new Paint();
paint.setStrokeWidth( 3 );
paint.setColor( Color.RED );
paint.setStyle(Paint.Style.STROKE );
paint.setAntiAlias( true );

Path path = getPath();
// DashPathEffect 画虚线,{10,15,20,25}  10 实线,15虚线,20实线,25虚线,
// 虚线绘制的时候会不断的循环这个数组,0表示偏移量
paint.setPathEffect( new DashPathEffect( new float[]{10,15,20,25}, 0) );
canvas.translate( 0,300 );
canvas.drawPath( path, paint );
}

具体用法:

// 步骤1:创建一个画笔
private Paint mPaint = new Paint();

// 步骤2:初始化画笔
// 根据需求设置画笔的各种属性,具体如下:

private void initPaint() {

    // 设置最基本的属性
    // 设置画笔颜色
    // 可直接引入Color类,如Color.red等
    mPaint.setColor(int color); 
    // 设置画笔模式
     mPaint.setStyle(Style style); 
    // Style有3种类型:
    // 类型1:Paint.Style.FILLANDSTROKE(描边+填充)
    // 类型2:Paint.Style.FILL(只填充不描边)
    // 类型3:Paint.Style.STROKE(只描边不填充)
    // 具体差别请看下图:
    // 特别注意:前两种就相差一条边
    // 若边细是看不出分别的;边粗就相当于加粗       
    
    //设置画笔的粗细
    mPaint.setStrokeWidth(float width)       
    // 如设置画笔宽度为10px
    mPaint.setStrokeWidth(10f);    

    // 不常设置的属性
    // 得到画笔的颜色     
    mPaint.getColor()      
    // 设置Shader
    // 即着色器,定义了图形的着色、外观
    // 可以绘制出多彩的图形
    // 具体请参考文章:http://blog.csdn.net/iispring/article/details/50500106
    Paint.setShader(Shader shader)  

    //设置画笔的a,r,p,g值
   mPaint.setARGB(int a, int r, int g, int b)      
     //设置透明度
    mPaint.setAlpha(int a)   
   //得到画笔的Alpha值
    mPaint.getAlpha()        


    // 对字体进行设置(大小、颜色)
    //设置字体大小
      mPaint.setTextSize(float textSize)       

    // 文字Style三种模式:
      mPaint.setStyle(Style style); 
    // 类型1:Paint.Style.FILLANDSTROKE(描边+填充)
    // 类型2:Paint.Style.FILL(只填充不描边)
    // 类型3:Paint.Style.STROKE(只描边不填充) 
    
  // 设置对齐方式   
  setTextAlign()
  // LEFT:左对齐
  // CENTER:居中对齐
  // RIGHT:右对齐

    //设置文本的下划线
      setUnderlineText(boolean underlineText)      
    
    //设置文本的删除线
    setStrikeThruText(boolean strikeThruText)    

     //设置文本粗体
    setFakeBoldText(boolean fakeBoldText)  
    
       // 设置斜体
    Paint.setTextSkewX(-0.5f);


    // 设置文字阴影
    Paint.setShadowLayer(5,5,5,Color.YELLOW);
 }

// 步骤3:在构造函数中初始化
public CarsonView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initPaint();
}

参考:https://www.jianshu.com/p/c6bbc5c6ae50

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容