尽管把自定义View比作盖1座房子,假如把自定义View比作盖1座房屋永利网上娱乐

上篇小说介绍了自定义View的成立流程,从宏观上提交了三个自定义View的成立步骤,本篇是上1篇文章的接轨,介绍了自定义View中三个供给的工具Canvas和Paint,从细节上更进一步的教学自定义View的详实绘制方法。借使把自定义View比作盖壹座房子,那么上篇小说就一定于教会了我们怎么一步步的搭建房子的骨架,而本篇小说将要教会我们的是为房子的龙骨添砖加瓦直至成型,甚至是怎么装修。

上篇作品介绍了自定义View的成立流程,从微观上提交了多少个自定义View的创造步骤,本篇是上一篇作品的接轨,介绍了自定义View中三个供给的工具Canvas和Paint,从细节上更进一步的讲解自定义View的事无巨细绘制方法。要是把自定义View比作盖1座房屋,那么上篇小说就一定于教会了笔者们怎么一步步的搭建房子的骨架,而本篇小说将要教会大家的是为房子的骨子添砖加瓦直至成型,甚至是怎么装修。

Canvas

为了后文更为便利的助教Canvas的常用方法的利用,大家先来做一些准备干活,创制贰个自定义View框架,先初阶化一下Paint画笔,并安装相关措施:

public class StudyView extends View {

    private Paint mPaint;
    private Context mContext;

    public StudyView(Context context) {
        super(context);
        init(context);
    }

    public StudyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStrokeWidth(5); // 设置笔尖宽度
        mPaint.setStyle(Paint.Style.STROKE); // 不填充
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

Canvas

为了后文更为便利的授课Canvas的常用方法的应用,大家先来做1些预备工作,创立一个自定义View框架,先初步化一下Paint画笔,并设置相关方法:

public class StudyView extends View {

    private Paint mPaint;
    private Context mContext;

    public StudyView(Context context) {
        super(context);
        init(context);
    }

    public StudyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStrokeWidth(5); // 设置笔尖宽度
        mPaint.setStyle(Paint.Style.STROKE); // 不填充
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

绘制圆弧和扇形

Canvas提供drawArc()方法,通过传递分化的参数可用来绘制圆弧和扇形,此措施有五个重载方法,详细参数如下:

  • drawArc(float left, float top, float right, float bottom, float
    startAngle, float sweepAngle, boolean useCenter, Paint paint)
  1. left:扇形或圆弧所占区域的左手界线x坐标
  2. top:扇形或圆弧所占区域的顶端界线y坐标
  3. right:右侧界线x坐标
  4. bottom:上边界线y坐标
  5. startAngle:扇形或圆弧的胚胎角度
  6. sweepAngle:扫过的角度
  7. userCenter:此参数能够知道为true正是画扇形,false就是画圆弧
  8. paint:画笔
  • drawArc(RectF oval, float startAngle, float sweepAngle, boolean
    useCenter, Paint paint)

此措施第三个参数是一个RectF类,也是境界,正是把三个艺术的left,top,right,bottom封装到了RectF类中,剩余参数与上2个格局1致。

接下去用着多个重载方法分别绘制三个90°的扇形和五个90°的拱形:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 绘制扇形
    canvas.drawArc(0, 0, 200, 200, 0, 90, true, mPaint);
    RectF rectF = new RectF(0, 0, 200, 200);
    canvas.drawArc(rectF, 180, 90, true, mPaint);

    // 绘制圆弧
    canvas.drawArc(300, 0, 500, 200, 0, 90, false, mPaint);
    RectF rectF1 = new RectF(300, 0, 500, 200);
    canvas.drawArc(rectF1, 180, 90, false, mPaint);
}

绘制效果如下图所示,此外索要表达的有些是,drawArc的第陆个参数startAngle中的角度,0°是指坐标系中第陆象限中与x重合的角度,顺时针方向代表角度增大的大势,如下图中革命线条所示。

永利网上娱乐 1

制图圆弧和扇形

Canvas提供drawArc()方法,通过传递分裂的参数可用来绘制圆弧和扇形,此办法有四个重载方法,详细参数如下:

  • drawArc(float left, float top, float right, float bottom, float
    startAngle, float sweepAngle, boolean useCenter, Paint paint)
  1. left:扇形或圆弧所占区域的左手界线x坐标
  2. top:扇形或圆弧所占区域的顶端界线y坐标
  3. right:左侧界线x坐标
  4. bottom:上面界线y坐标
  5. startAngle:扇形或圆弧的序幕角度
  6. sweepAngle:扫过的角度
  7. userCenter:此参数能够知道为true便是画扇形,false便是画圆弧
  8. paint:画笔
  • drawArc(RectF oval, float startAngle, float sweepAngle, boolean
    useCenter, Paint paint)

此办法第贰个参数是三个RectF类,也是境界,就是把三个艺术的left,top,right,bottom封装到了RectF类中,剩余参数与上一个格局同样。

接下去用着五个重载方法分别绘制多个90°的扇形和多个90°的半圆形:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // 绘制扇形
    canvas.drawArc(0, 0, 200, 200, 0, 90, true, mPaint);
    RectF rectF = new RectF(0, 0, 200, 200);
    canvas.drawArc(rectF, 180, 90, true, mPaint);

    // 绘制圆弧
    canvas.drawArc(300, 0, 500, 200, 0, 90, false, mPaint);
    RectF rectF1 = new RectF(300, 0, 500, 200);
    canvas.drawArc(rectF1, 180, 90, false, mPaint);
}

绘制效果如下图所示,此外索要证实的一点是,drawArc的第多少个参数startAngle中的角度,0°是指坐标系中第5象限中与x重合的角度,顺时针方向代表角度增大的倾向,如下图中革命线条所示。

永利网上娱乐 2

绘制Bitmap

在Canvas中提供了drawBitmap方法,此措施可以让大家直接获取一张图纸绘制到画布上,有了它能够让大家的自定义View为虎傅翼,同时也让大家兑现部分错综复杂效果有了三个一发便于的门径。上面是drawBitmap的多少个比较常用的重载方法:

  • drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
  1. bitmap:Bitmap财富文件
  2. left和top:代表了图片左上角落入的地方坐标。
  3. top:看2
  4. paint:画笔
  • drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
  1. src:在Bitmap图片上截取壹有的作为绘制源,可null
  2. det:将绘制指标拉伸平铺到det内定的矩形中
  • drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
    同第三个重载方法,大约一毛壹样。

  • drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

  1. matrix:Matrix的参数字传送入是的drawBitmap作用变得极度强硬,让此格局有意思了许多,通过matrix能够实现图片的运动(postTranslate())、缩放(postScale())、旋转(postRotate())、错切(postSkew())等等花式炫酷效果,由于Matrix的用法稍微多一些,篇幅限制,那里就先1带而过了,感兴趣的爱人能够活动探索。

在onDraw方法中drawBitmap的上述重载方法,注意在利用完Bitmap之后记得用Bitmap.recycle()来回收掉能源,防止备oom。

/** drawBitmap */
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), android.R.mipmap.sym_def_app_icon);
// 绘制图片
canvas.drawBitmap(bitmap, 0, 300, null);
// 将图片拉伸平铺在RectF矩形内
canvas.drawBitmap(bitmap, null, new RectF(200, 300, 500, 500), null);
// 截取图片的四分之一拉伸平铺在RectF矩形内
canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2), new RectF(500, 300, 800, 500), null);

Matrix matrix = new Matrix();
matrix.postTranslate(800, 300); // 将bitmap平移到此位置
canvas.drawBitmap(bitmap, matrix, mPaint);

// 为防止oom,及时回收bitmap
bitmap.recycle();

职能如下图(红框内)。

永利网上娱乐 3

绘制Bitmap

在Canvas中提供了drawBitmap方法,此措施能够让大家从来拿走一张图纸绘制到画布上,有了它能够让我们的自定义View猛虎添翼,同时也让我们兑现部分繁杂效果有了2个更为惠及的路子。上面是drawBitmap的几个相比常用的重载方法:

  • drawBitmap(Bitmap bitmap, float left, float top, Paint paint)
  1. bitmap:Bitmap资源文件
  2. left和top:代表了图片左上角落入的地点坐标。
  3. top:看2
  4. paint:画笔
  • drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)
  1. src:在Bitmap图片上截取1有个别作为绘制源,可null
  2. det:将绘制目的拉伸平铺到det内定的矩形中
  • drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
    同第一个重载方法,大致一毛壹样。

  • drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)

  1. matrix:Matrix的参数字传送入是的drawBitmap效能变得非凡强硬,让此方式有意思了累累,通过matrix能够完结图片的移动(postTranslate())、缩放(postScale())、旋转(postRotate())、错切(postSkew())等等花式炫酷效果,由于Matrix的用法稍微多一些,篇幅限制,那里就先1带而过了,感兴趣的爱侣能够自动探索。

在onDraw方法中drawBitmap的如上海重机厂载方法,注目的在于动用完Bitmap之后记得用Bitmap.recycle()来回收掉财富,以幸免oom。

/** drawBitmap */
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), android.R.mipmap.sym_def_app_icon);
// 绘制图片
canvas.drawBitmap(bitmap, 0, 300, null);
// 将图片拉伸平铺在RectF矩形内
canvas.drawBitmap(bitmap, null, new RectF(200, 300, 500, 500), null);
// 截取图片的四分之一拉伸平铺在RectF矩形内
canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2), new RectF(500, 300, 800, 500), null);

Matrix matrix = new Matrix();
matrix.postTranslate(800, 300); // 将bitmap平移到此位置
canvas.drawBitmap(bitmap, matrix, mPaint);

// 为防止oom,及时回收bitmap
bitmap.recycle();

作用如下图(红框内)。

永利网上娱乐 4

绘图圆形

  • drawCircle(float cx, float cy, float radius, Paint paint)
  1. cx:圆心x坐标
  2. cy:圆心y坐标
  3. radius:半径

canvas.drawCircle(100, 700, 100, mPaint);

成效如下图:

永利网上娱乐 5

绘图圆形

  • drawCircle(float cx, float cy, float radius, Paint paint)
  1. cx:圆心x坐标
  2. cy:圆心y坐标
  3. radius:半径

canvas.drawCircle(100, 700, 100, mPaint);

职能如下图:

永利网上娱乐 6

绘制点

  • drawPoint(float x, float y, Paint paint)
  1. x:点的x坐标
  2. y:点的y坐标
  • drawPoints(float[] pts, Paint paint) 绘制1组点
  1. pts:float数组,两位为一组,两两构成代表x、y坐标,例如:pts[0]、pts[1]代表第三个点的x、y坐标,pts[2]、pts[3]表示第四个点的x、y坐标,依次类推。
  • drawPoints(float[] pts, int offset, int count, Paint paint)
    绘制壹组点
  1. pts:float数组,两位为一组,两两重组代表x、y坐标,例如:pts[0]、pts[1]表示首先个点的x、y坐标,pts[2]、pts[3]意味着第壹个点的x、y坐标,依次类推。
  2. offset:代表数组开端跳过多少个只伊始绘制点,注意那里不是指数组的下标,而是意味着跳过多少个值。
  3. count:在跳过offset个值后,处理多少个值,注意那里的count不是代表点的个数,而是表示数组中值的个数。

canvas.drawPoint(100, 700, mPaint); // 绘制一个点

float[] points = new float[] {
    130, 700,
    160, 700,
    190, 700,
    210, 700,
    240, 700
};

canvas.drawPoints(points, 2, 4, mPaint); // 绘制一组点(代表跳过前两个值,处理4个值,也就是实际绘制2个点)

功效如下图:

永利网上娱乐 7

绘制点

  • drawPoint(float x, float y, Paint paint)
  1. x:点的x坐标
  2. y:点的y坐标
  • drawPoints(float[] pts, Paint paint) 绘制一组点
  1. pts:float数组,两位为1组,两两组合代表x、y坐标,例如:pts[0]、pts[1]代表首先个点的x、y坐标,pts[2]、pts[3]表示第一个点的x、y坐标,依次类推。
  • drawPoints(float[] pts, int offset, int count, Paint paint)
    绘制一组点
  1. pts:float数组,两位为壹组,两两整合代表x、y坐标,例如:pts[0]、pts[1]表示第2个点的x、y坐标,pts[2]、pts[3]意味着第1个点的x、y坐标,依次类推。
  2. offset:代表数组开头跳过多少个只先河绘制点,注意那里不是指数组的下标,而是意味着跳过几个值。
  3. count:在跳过offset个值后,处理多少个值,注意那里的count不是代表点的个数,而是表示数组中值的个数。

canvas.drawPoint(100, 700, mPaint); // 绘制一个点

float[] points = new float[] {
    130, 700,
    160, 700,
    190, 700,
    210, 700,
    240, 700
};

canvas.drawPoints(points, 2, 4, mPaint); // 绘制一组点(代表跳过前两个值,处理4个值,也就是实际绘制2个点)

效率如下图:

永利网上娱乐 8

绘图椭圆

  • drawOval(float left, float top, float right, float bottom, Paint
    paint)
  1. left
  2. top
  3. right
  4. bottom

在left、top、right、bottom围成的区域内绘制多个椭圆。

  • drawOval(RectF oval, Paint paint)
  1. 将首先个重载方法的left、top、right、bottom封装到RectF类中,与扇形的重载方法异曲同工。

RectF rectF2 = new RectF(300, 600, 700, 800); // 创建一个RectF
canvas.drawOval(rectF2, mPaint);

作用如下图:

永利网上娱乐 9

绘制椭圆

  • drawOval(float left, float top, float right, float bottom, Paint
    paint)
  1. left
  2. top
  3. right
  4. bottom

在left、top、right、bottom围成的区域内绘制2个椭圆。

  • drawOval(RectF oval, Paint paint)
  1. 将率先个重载方法的left、top、right、bottom封装到RectF类中,与扇形的重载方法异曲同工。

RectF rectF2 = new RectF(300, 600, 700, 800); // 创建一个RectF
canvas.drawOval(rectF2, mPaint);

功能如下图:

永利网上娱乐 10

制图矩形

  • drawRect(float left, float top, float right, float bottom, Paint
    paint)
  • drawRect(Rect r, Paint paint)
  • drawRect(RectF rect, Paint paint)

drawRect的参数十三分好驾驭,那里就不啰嗦了,直接上代码看作用:

canvas.drawRect(rectF2, mPaint);

注:那里的rectF二即上文绘制椭圆时制造的RectF对象。

永利网上娱乐 11

绘制矩形

  • drawRect(float left, float top, float right, float bottom, Paint
    paint)
  • drawRect(Rect r, Paint paint)
  • drawRect(RectF rect, Paint paint)

drawRect的参数十三分好驾驭,那里就不啰嗦了,直接上代码看功能:

canvas.drawRect(rectF2, mPaint);

注:那里的rectF二即上文绘制椭圆时创设的RectF对象。

永利网上娱乐 12

绘图圆角矩形

  • drawRoundRect(float left, float top, float right, float bottom,
    float rx, float ry, Paint paint)
  • drawRoundRect(RectF rect, float rx, float ry, Paint paint)

drawRoundRect是绘制圆角矩形,用法和drawRect类似,唯一分歧的是多了七个参数:

  1. rx:x轴方向的圆角弧度
  2. ry:y轴方向的圆角弧度

上代码,看效果:

canvas.drawRoundRect(rectF2, 60, 30, mPaint);

此地为了卓越多少个趋势的圆角弧度,特地将rx和ry设置差异比较大,效果如下图:

永利网上娱乐 13

制图圆角矩形

  • drawRoundRect(float left, float top, float right, float bottom,
    float rx, float ry, Paint paint)
  • drawRoundRect(RectF rect, float rx, float ry, Paint paint)

drawRoundRect是绘制圆角矩形,用法和drawRect类似,唯一分歧的是多了多个参数:

  1. rx:x轴方向的圆角弧度
  2. ry:y轴方向的圆角弧度

上代码,看效果:

canvas.drawRoundRect(rectF2, 60, 30, mPaint);

那边为了突出五个样子的圆角弧度,特地将rx和ry设置差别比较大,效果如下图:

永利网上娱乐 14

绘制直线

  • drawLine(float startX, float startY, float stopX, float stopY, Paint
    paint)
  • drawLines(float[] pts, int offset, int count, Paint paint)
  • drawLines(float[] pts, Paint paint)

drawLine和drawLines三个是绘制二个点,叁个是绘制1组点,在那之中drawLines中的float数组中多个值为①组点,其用法能够参照drawPoints。

canvas.drawLine(100, 820, 800, 820, mPaint);

float[] lines = new float[]{
        100f, 850f, 800f, 850f,
        100f, 900f, 800f, 900f,
        100f, 950f, 800f, 950f
};
canvas.drawLines(lines, mPaint); // 按floats数组中,四个数为1组,绘制多条线

职能如下图:

永利网上娱乐 15

绘制直线

  • drawLine(float startX, float startY, float stopX, float stopY, Paint
    paint)
  • drawLines(float[] pts, int offset, int count, Paint paint)
  • drawLines(float[] pts, Paint paint)

drawLine和drawLines三个是绘制一个点,一个是绘制1组点,当中drawLines中的float数组中几个值为1组点,其用法能够参照drawPoints。

canvas.drawLine(100, 820, 800, 820, mPaint);

float[] lines = new float[]{
        100f, 850f, 800f, 850f,
        100f, 900f, 800f, 900f,
        100f, 950f, 800f, 950f
};
canvas.drawLines(lines, mPaint); // 按floats数组中,四个数为1组,绘制多条线

功能如下图:

永利网上娱乐 16

drawPath() 绘制不规则图形

上边的那个Canvas方法纵然已经很强劲了,但是大家只要想要绘制一些非正常的图形怎么做,那时候就要用到无敌的drawPath()方法了,通过对Path进行设置差异的坐标、添加分裂图形,最后传入drawPath方法中得以绘制出复杂的且不规则的形制。以下是drawPath的章程及参数:

  • drawPath(Path path, Paint paint)

此间的机要参数正是Path,Path类的方法较多,大多数用法类似,那里挑多少个说一下:

  • Path类
  1. addArc(RectF oval, float startAngle, float sweepAngle)
    往path里面添加2个半圆
  2. addCircle(float x, float y, float radius, Path.Direction dir)
    添加3个圆形
  3. addOval(RectF oval, Path.Direction dir) 添加3个椭圆
  4. addRect(RectF rect, Path.Direction dir) 添加一个矩形
  5. lineTo(float x, float y) 连线到坐标(x,y)
  6. moveTo(float x, float y) 将path绘制点运动到坐标(x,y)
  7. close()
    用直线闭合图形,调用此形式后,path会将最后一处点与开端用直线连接起来,path起先点为moveTo()方法的坐标上,假如未有调用moveTo()起首点将暗许为(0,0)坐标。

接下去使用drawPath绘制2个阶梯:

// 使用 Path 绘制一个楼梯
Path path = new Path();
path.lineTo(0, 1000);
path.lineTo(100, 1000);
path.lineTo(100, 1100);
path.lineTo(200, 1100);
path.lineTo(200, 1200);
path.lineTo(300, 1200);
path.lineTo(300, 1300);
path.lineTo(400, 1300);
path.lineTo(400, 1400);
path.lineTo(0, 1400);
path.lineTo(0, 1000);
path.close();
canvas.drawPath(path, mPaint);

效益如下图:

永利网上娱乐 17

再用drawPath方法绘制四个Android小机器人:

/ 使用 Path 绘制一个Android机器人
// 绘制两个触角
path.reset();
path.moveTo(625, 1050);
path.lineTo(650, 1120);
path.moveTo(775, 1050);
path.lineTo(750, 1120);

path.addArc(new RectF(600, 1100, 800, 1300), 180, 180); // 绘制头部
path.addCircle(666.66f, 1150, 10, Path.Direction.CW); // 绘制眼睛,CW:顺时针绘制, CCW:逆时针绘制
path.addCircle(733.33f, 1150, 10, Path.Direction.CW);
path.addRect(new RectF(600, 1200, 800, 1300), Path.Direction.CW);  // 身体
canvas.drawPath(path, mPaint);

成效图如下:

永利网上娱乐 18

最终,上文中Canvas示例的整整代码如下:

public class StudyView extends View {

    private Paint mPaint;
    private Context mContext;

    public StudyView(Context context) {
        super(context);
        init(context);
    }

    public StudyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStrokeWidth(5); // 设置笔尖宽度
        mPaint.setStyle(Paint.Style.STROKE); // 不填充
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /** 1、drawArc */

        // 绘制扇形
        canvas.drawArc(0, 0, 200, 200, 0, 90, true, mPaint);
        RectF rectF = new RectF(0, 0, 200, 200);
        canvas.drawArc(rectF, 180, 90, true, mPaint);

        // 绘制圆弧
        canvas.drawArc(300, 0, 500, 200, 0, 90, false, mPaint);
        RectF rectF1 = new RectF(300, 0, 500, 200);
        canvas.drawArc(rectF1, 180, 90, false, mPaint);

        /** 2、drawBitmap */
        Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), android.R.mipmap.sym_def_app_icon);
        // 绘制图片
        canvas.drawBitmap(bitmap, 0, 300, null);
        // 将图片拉伸平铺在RectF矩形内
        canvas.drawBitmap(bitmap, null, new RectF(200, 300, 500, 500), null);
        // 截取图片的四分之一拉伸平铺在RectF矩形内
        canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2), new RectF(500, 300, 800, 500), null);

        Matrix matrix = new Matrix();
        matrix.postTranslate(800, 300); // 将bitmap平移到此位置
        canvas.drawBitmap(bitmap, matrix, mPaint);

        // 为防止oom,及时回收bitmap
        bitmap.recycle();

        /** 3、drawCircle */
        canvas.drawCircle(100, 700, 100, mPaint);

        /** 4、绘制一个点 */
        canvas.drawPoint(100, 700, mPaint); // 绘制一个点

        float[] points = new float[] {
            130, 700,
            160, 700,
            190, 700,
            210, 700,
            240, 700
        };

        canvas.drawPoints(points, 2, 4, mPaint); // 绘制一组点(代表跳过前两个值,处理4个值,也就是实际绘制2个点)


        RectF rectF2 = new RectF(300, 600, 700, 800); // 创建一个RectF

        /** 5、drawOval 绘制椭圆 */
        canvas.drawOval(rectF2, mPaint);

        /** 6、drawRect 绘制矩形*/
        canvas.drawRect(rectF2, mPaint);
        canvas.drawRoundRect(rectF2, 60, 30, mPaint);

        /** 7、drawLine */
        canvas.drawLine(100, 820, 800, 820, mPaint);

        float[] lines = new float[]{
                100f, 850f, 800f, 850f,
                100f, 900f, 800f, 900f,
                100f, 950f, 800f, 950f
        };
        canvas.drawLines(lines, mPaint); // 按floats数组中,四个数为1组,绘制多条线


        /** 8、drawPath */

        // 使用 Path 绘制一个楼梯
        Path path = new Path();
        path.moveTo(0, 1000);
        path.lineTo(100, 1000);
        path.lineTo(100, 1100);
        path.lineTo(200, 1100);
        path.lineTo(200, 1200);
        path.lineTo(300, 1200);
        path.lineTo(300, 1300);
        path.lineTo(400, 1300);
        path.lineTo(400, 1400);
        path.close();
        canvas.drawPath(path, mPaint);

        // 使用 Path 绘制一个Android机器人

        // 绘制两个触角
        path.reset();
        path.moveTo(625, 1050);
        path.lineTo(650, 1120);
        path.moveTo(775, 1050);
        path.lineTo(750, 1120);

        path.addArc(new RectF(600, 1100, 800, 1300), 180, 180); // 绘制头部
        path.addCircle(666.66f, 1150, 10, Path.Direction.CW); // 绘制眼睛,CW:顺时针绘制, CCW:逆时针绘制
        path.addCircle(733.33f, 1150, 10, Path.Direction.CW);
        path.addRect(new RectF(600, 1200, 800, 1300), Path.Direction.CW);  // 身体
        canvas.drawPath(path, mPaint);
    }
}

全体意义图如下:

永利网上娱乐 19

其实Canvas除了能够绘制图形之外,还足以绘制文字,Canvas的绘图文字的法子有drawText()、drawTextOnPath()、drawTextRun()等形式,在绘制文字是和Paint的重组愈加严峻,所以讲绘制文字的点子放在下文和Paint一起讲或然效果会更好一些,好了,废话不多说了,接下去大家就从头Paint的稿子。

drawPath() 绘制不规则图形

上边的那些Canvas方法尽管已经很强劲了,可是大家假设想要绘制一些难堪的图形咋办,那时候就要用到有力的drawPath()方法了,通过对Path进行安装不一致的坐标、添加不相同图形,最终传入drawPath方法中得以绘制出复杂的且不规则的形态。以下是drawPath的不2诀窍及参数:

  • drawPath(Path path, Paint paint)

那边的重大参数便是Path,Path类的办法较多,大多数用法类似,那里挑多少个说一下:

  • Path类
  1. addArc(RectF oval, float startAngle, float sweepAngle)
    往path里面添加四个半圆
  2. addCircle(float x, float y, float radius, Path.Direction dir)
    添加三个圆形
  3. addOval(RectF oval, Path.Direction dir) 添加二个椭圆
  4. addRect(RectF rect, Path.Direction dir) 添加3个矩形
  5. lineTo(float x, float y) 连线到坐标(x,y)
  6. moveTo(float x, float y) 将path绘制点运动到坐标(x,y)
  7. close()
    用直线闭合图形,调用此方式后,path会将最后1处点与开端用直线连接起来,path初步点为moveTo()方法的坐标上,若是未有调用moveTo()起先点将默许为(0,0)坐标。

接下去使用draw帕特h绘制一个楼梯:

// 使用 Path 绘制一个楼梯
Path path = new Path();
path.lineTo(0, 1000);
path.lineTo(100, 1000);
path.lineTo(100, 1100);
path.lineTo(200, 1100);
path.lineTo(200, 1200);
path.lineTo(300, 1200);
path.lineTo(300, 1300);
path.lineTo(400, 1300);
path.lineTo(400, 1400);
path.lineTo(0, 1400);
path.lineTo(0, 1000);
path.close();
canvas.drawPath(path, mPaint);

功能如下图:

永利网上娱乐 20

再用drawPath方法绘制一个Android小机器人:

/ 使用 Path 绘制一个Android机器人
// 绘制两个触角
path.reset();
path.moveTo(625, 1050);
path.lineTo(650, 1120);
path.moveTo(775, 1050);
path.lineTo(750, 1120);

path.addArc(new RectF(600, 1100, 800, 1300), 180, 180); // 绘制头部
path.addCircle(666.66f, 1150, 10, Path.Direction.CW); // 绘制眼睛,CW:顺时针绘制, CCW:逆时针绘制
path.addCircle(733.33f, 1150, 10, Path.Direction.CW);
path.addRect(new RectF(600, 1200, 800, 1300), Path.Direction.CW);  // 身体
canvas.drawPath(path, mPaint);

效用图如下:

永利网上娱乐 21

末尾,上文中Canvas示例的万事代码如下:

public class StudyView extends View {

    private Paint mPaint;
    private Context mContext;

    public StudyView(Context context) {
        super(context);
        init(context);
    }

    public StudyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true); // 消除锯齿
        mPaint.setStrokeWidth(5); // 设置笔尖宽度
        mPaint.setStyle(Paint.Style.STROKE); // 不填充
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /** 1、drawArc */

        // 绘制扇形
        canvas.drawArc(0, 0, 200, 200, 0, 90, true, mPaint);
        RectF rectF = new RectF(0, 0, 200, 200);
        canvas.drawArc(rectF, 180, 90, true, mPaint);

        // 绘制圆弧
        canvas.drawArc(300, 0, 500, 200, 0, 90, false, mPaint);
        RectF rectF1 = new RectF(300, 0, 500, 200);
        canvas.drawArc(rectF1, 180, 90, false, mPaint);

        /** 2、drawBitmap */
        Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), android.R.mipmap.sym_def_app_icon);
        // 绘制图片
        canvas.drawBitmap(bitmap, 0, 300, null);
        // 将图片拉伸平铺在RectF矩形内
        canvas.drawBitmap(bitmap, null, new RectF(200, 300, 500, 500), null);
        // 截取图片的四分之一拉伸平铺在RectF矩形内
        canvas.drawBitmap(bitmap, new Rect(0, 0, bitmap.getWidth()/2, bitmap.getHeight()/2), new RectF(500, 300, 800, 500), null);

        Matrix matrix = new Matrix();
        matrix.postTranslate(800, 300); // 将bitmap平移到此位置
        canvas.drawBitmap(bitmap, matrix, mPaint);

        // 为防止oom,及时回收bitmap
        bitmap.recycle();

        /** 3、drawCircle */
        canvas.drawCircle(100, 700, 100, mPaint);

        /** 4、绘制一个点 */
        canvas.drawPoint(100, 700, mPaint); // 绘制一个点

        float[] points = new float[] {
            130, 700,
            160, 700,
            190, 700,
            210, 700,
            240, 700
        };

        canvas.drawPoints(points, 2, 4, mPaint); // 绘制一组点(代表跳过前两个值,处理4个值,也就是实际绘制2个点)


        RectF rectF2 = new RectF(300, 600, 700, 800); // 创建一个RectF

        /** 5、drawOval 绘制椭圆 */
        canvas.drawOval(rectF2, mPaint);

        /** 6、drawRect 绘制矩形*/
        canvas.drawRect(rectF2, mPaint);
        canvas.drawRoundRect(rectF2, 60, 30, mPaint);

        /** 7、drawLine */
        canvas.drawLine(100, 820, 800, 820, mPaint);

        float[] lines = new float[]{
                100f, 850f, 800f, 850f,
                100f, 900f, 800f, 900f,
                100f, 950f, 800f, 950f
        };
        canvas.drawLines(lines, mPaint); // 按floats数组中,四个数为1组,绘制多条线


        /** 8、drawPath */

        // 使用 Path 绘制一个楼梯
        Path path = new Path();
        path.moveTo(0, 1000);
        path.lineTo(100, 1000);
        path.lineTo(100, 1100);
        path.lineTo(200, 1100);
        path.lineTo(200, 1200);
        path.lineTo(300, 1200);
        path.lineTo(300, 1300);
        path.lineTo(400, 1300);
        path.lineTo(400, 1400);
        path.close();
        canvas.drawPath(path, mPaint);

        // 使用 Path 绘制一个Android机器人

        // 绘制两个触角
        path.reset();
        path.moveTo(625, 1050);
        path.lineTo(650, 1120);
        path.moveTo(775, 1050);
        path.lineTo(750, 1120);

        path.addArc(new RectF(600, 1100, 800, 1300), 180, 180); // 绘制头部
        path.addCircle(666.66f, 1150, 10, Path.Direction.CW); // 绘制眼睛,CW:顺时针绘制, CCW:逆时针绘制
        path.addCircle(733.33f, 1150, 10, Path.Direction.CW);
        path.addRect(new RectF(600, 1200, 800, 1300), Path.Direction.CW);  // 身体
        canvas.drawPath(path, mPaint);
    }
}

完整意义图如下:

永利网上娱乐 22

实际上Canvas除了能够绘制图形之外,还足以绘制文字,Canvas的绘图像和文字字的点子有drawText()、drawTextOnPath()、drawTextRun()等艺术,在绘制文字是和Paint的组成愈加严刻,所以讲绘制文字的秘籍放在下文和Paint一起讲或者效果会更好一些,好了,废话不多说了,接下去大家就起来Paint的篇章。

Paint

为了尤其清晰的讲授Paint的用法,先来新建三个自定义类,暂叫PaintStudyView,接下去创造3个它的光景骨架,在此类中定义了部分变量,变量的意义请见注释:

public class PaintStudyView extends View {

    private Paint mTextPaint;  // 绘制文字的Paint
    private Paint mPointPaint; // 绘制参考点的Paint
    private Context mContext;

    private final static float Y_SPACE = 100; // y轴方向的间距

    public PaintStudyView(Context context) {
        super(context);
        init(context);
    }

    public PaintStudyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true); // 消除锯齿
        mTextPaint.setStrokeWidth(1); // 设置笔尖宽度
        mTextPaint.setStyle(Paint.Style.FILL); // 填充
        mTextPaint.setTextSize(30);

        mPointPaint = new Paint();
        mPointPaint.setAntiAlias(true);
        mPointPaint.setStrokeWidth(5);
        mPointPaint.setColor(Color.RED); // 将参考点的Paint设置为红色
        mPointPaint.setStyle(Paint.Style.STROKE);// 不填充
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

Paint

为了进一步分明的任课Paint的用法,先来新建多少个自定义类,暂叫PaintStudyView,接下去创建一个它的大致骨架,在此类中定义了有的变量,变量的含义请见注释:

public class PaintStudyView extends View {

    private Paint mTextPaint;  // 绘制文字的Paint
    private Paint mPointPaint; // 绘制参考点的Paint
    private Context mContext;

    private final static float Y_SPACE = 100; // y轴方向的间距

    public PaintStudyView(Context context) {
        super(context);
        init(context);
    }

    public PaintStudyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true); // 消除锯齿
        mTextPaint.setStrokeWidth(1); // 设置笔尖宽度
        mTextPaint.setStyle(Paint.Style.FILL); // 填充
        mTextPaint.setTextSize(30);

        mPointPaint = new Paint();
        mPointPaint.setAntiAlias(true);
        mPointPaint.setStrokeWidth(5);
        mPointPaint.setColor(Color.RED); // 将参考点的Paint设置为红色
        mPointPaint.setStyle(Paint.Style.STROKE);// 不填充
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
}

Canvas的绘图像和文字字的相干措施:

Canvas的绘图文字的连带办法:

drawText()的重载方法

drawText()
是Canvas的绘图像和文字字中的最长用的法子,它只好依据从左至右的常见格局来绘制文字。

  • drawText(String text, float x, float y, Paint paint)
  1. text:待绘制的文字内容
  2. x:文字绘制地点的x坐标
  3. y:文字绘制地点的y坐标
  4. paint:Paint画笔,能够通过Paint.setTextAlign()来控制文字的方向,有:Paint.Align.LEFT(居左),Paint.阿里gn.ENCOREIGHT(居右),Paint.Align.CENTERAV四(居中)四个岗位。
  • drawText(String text, int start, int end, float x, float y, Paint
    paint)
  1. start:代表从text中的第多少个字符开头截取绘制,包蕴第start个字符。
  2. end:代表截取到text的第多少个字符,不带有第end个字符。

比如:笔者是三个自定义View的控件,start=1,end=6,截取后为:是1个自定

上边三个重载方法能够参见第三个很不难就能通晓:

  • drawText(CharSequence text, int start, int end, float x, float y,
    Paint paint)
  • drawText(char[] text, int index, int count, float x, float y,
    Paint paint)

以下示例表明了文字的不等职位,同时也验证了第2个和第几个重载方法对字符串截取时的用法:

String str = "我是一个自定义View的控件";// 待绘制文字

float x = getWidth() / 2;
float y = 100;
canvas.drawPoint(x, y, mPointPaint); // 绘制参考点,便于观察文字处于x,y坐标的位置,从而来学习setTextAlign()方法

mTextPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText(str, x, y, mTextPaint);

y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
mTextPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(str, 0, 6, x, y, mTextPaint);

y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
mTextPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(str.toCharArray(), 1, 6, x, y, mTextPaint);

成效图如下:

永利网上娱乐 23

个中的红点为额外添加的参照坐标,指标是为了特出setTextAlign中参数的任务。

drawText()的重载方法

drawText()
是Canvas的绘图像和文字字中的最长用的法子,它不得不遵照从左至右的家常格局来绘制文字。

  • drawText(String text, float x, float y, Paint paint)
  1. text:待绘制的文字内容
  2. x:文字绘制地点的x坐标
  3. y:文字绘制地方的y坐标
  4. paint:Paint画笔,能够通过Paint.setTextAlign()来决定文字的方位,有:Paint.Align.LEFT(居左),Paint.Align.奥迪Q7IGHT(居右),Paint.Align.CENTEHummerH贰(居中)八个岗位。
  • drawText(String text, int start, int end, float x, float y, Paint
    paint)
  1. start:代表从text中的第几个字符初阶截取绘制,包涵第start个字符。
  2. end:代表截取到text的第几个字符,不蕴涵第end个字符。

诸如:笔者是3个自定义View的控件,start=一,end=陆,截取后为:是多个自定

下边多个重载方法能够参照第一个很简单就能明了:

  • drawText(CharSequence text, int start, int end, float x, float y,
    Paint paint)
  • drawText(char[] text, int index, int count, float x, float y,
    Paint paint)

以下示例表达了文字的不如任务,同时也表达了第贰个和第多个重载方法对字符串截取时的用法:

String str = "我是一个自定义View的控件";// 待绘制文字

float x = getWidth() / 2;
float y = 100;
canvas.drawPoint(x, y, mPointPaint); // 绘制参考点,便于观察文字处于x,y坐标的位置,从而来学习setTextAlign()方法

mTextPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText(str, x, y, mTextPaint);

y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
mTextPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText(str, 0, 6, x, y, mTextPaint);

y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
mTextPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(str.toCharArray(), 1, 6, x, y, mTextPaint);

功能图如下:

永利网上娱乐 24

其间的红点为额外添加的参阅坐标,目标是为着优秀setTextAlign中参数的职责。

drawTextOnPath()的重载方法

drawTextOnPath()
由艺术名字大家就能够看出来他能够遵循帕特h的走一贯绘制文字,例如大家在path中传唱1个弧形,那么绘制出来的文字走向正是圆弧状的,是否很酷,来看一下它的重载方法:

  • drawTextOnPath(String text, Path path, float hOffset, float vOffset,
    Paint paint)
  1. text:同drawText的第二个参数。
  2. path:Path参数,用法在前文已经说过了。
  3. hOffset:水平方向的偏移量。
  4. vOffset:垂直方向的偏移量。

关键点:有有个别必将要提的正是,那里的hOffset是相持于path路径的水平偏移量,而vOffset也是绝对于path路径的垂直偏移量,这么说只怕还某些不精通,结合上面包车型客车言传身教来验证,请密切回味那里的意思:

// 1、下开口圆弧方向绘制文字
mTextPaint.setTextAlign(Paint.Align.LEFT);
y += Y_SPACE;
Path path = new Path();
path.addArc(new RectF(x - 150, y, x + 150, y + 300), 180,180);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint); // 按照path路径绘制文字,不偏移
canvas.drawTextOnPath(str, path, 30, 30, mTextPaint);// 向水平、垂直方向各偏移30
canvas.drawTextOnPath(str, path, 60, 60, mTextPaint);// 向水平、垂直方向各偏移60

// 2、上开口圆弧方向绘制文字
path.reset();
y += Y_SPACE;
path.addArc(new RectF(x - 150, y, x + 150, y + 300), 0, 180);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint);
canvas.drawTextOnPath(str, path, 30, 30, mTextPaint);
canvas.drawTextOnPath(str, path, 60, 60, mTextPaint);
path.close();

// 3、竖直方向绘制文字
path.reset();
path.moveTo(200, y);
path.lineTo(200, y + 4 * Y_SPACE);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint);
canvas.drawTextOnPath(str, path, 30, 60, mTextPaint);


y += Y_SPACE;
y += Y_SPACE;
y += Y_SPACE;
y += Y_SPACE;

// 4、水平方向绘制文字
path.reset();
path.moveTo(x, y);
path.lineTo(x + 4 * Y_SPACE, y);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint);
canvas.drawTextOnPath(str, path, 30, 60, mTextPaint);

如下是效果图,注意看图片中的淡白紫部分,青绿的线是用代码绘制出来的path参考线,砖红的箭头是path的水平和垂直方向的走向,结合下图能够更好的知情drawTextOnPath的hOffset和vOffset参数。

永利网上娱乐 25

  • drawTextOnPath(char[] text, int index, int count, Path path, float
    hOffset, float vOffset, Paint paint)

以此艺术的套路想必不用解释了。

drawTextOnPath()的重载方法

drawTextOnPath()
由艺术名字大家就能够看出来他能够依据Path的走一贯绘制文字,例如我们在path中流传一个半圆,那么绘制出来的文字走向正是圆弧状的,是或不是很酷,来看一下它的重载方法:

  • drawTextOnPath(String text, Path path, float hOffset, float vOffset,
    Paint paint)
  1. text:同drawText的首先个参数。
  2. path:Path参数,用法在前文已经说过了。
  3. hOffset:水平方向的偏移量。
  4. vOffset:垂直方向的偏移量。

关键点:有某个早晚要提的就是,这里的hOffset是争执于path路径的品位偏移量,而vOffset也是相对于path路径的垂直偏移量,这么说或然还有些不掌握,结合上面的言传身教来验证,请仔细回味这里的意趣:

// 1、下开口圆弧方向绘制文字
mTextPaint.setTextAlign(Paint.Align.LEFT);
y += Y_SPACE;
Path path = new Path();
path.addArc(new RectF(x - 150, y, x + 150, y + 300), 180,180);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint); // 按照path路径绘制文字,不偏移
canvas.drawTextOnPath(str, path, 30, 30, mTextPaint);// 向水平、垂直方向各偏移30
canvas.drawTextOnPath(str, path, 60, 60, mTextPaint);// 向水平、垂直方向各偏移60

// 2、上开口圆弧方向绘制文字
path.reset();
y += Y_SPACE;
path.addArc(new RectF(x - 150, y, x + 150, y + 300), 0, 180);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint);
canvas.drawTextOnPath(str, path, 30, 30, mTextPaint);
canvas.drawTextOnPath(str, path, 60, 60, mTextPaint);
path.close();

// 3、竖直方向绘制文字
path.reset();
path.moveTo(200, y);
path.lineTo(200, y + 4 * Y_SPACE);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint);
canvas.drawTextOnPath(str, path, 30, 60, mTextPaint);


y += Y_SPACE;
y += Y_SPACE;
y += Y_SPACE;
y += Y_SPACE;

// 4、水平方向绘制文字
path.reset();
path.moveTo(x, y);
path.lineTo(x + 4 * Y_SPACE, y);
canvas.drawPath(path, mPointPaint); // 参考弧度线
canvas.drawTextOnPath(str, path, 0, 0, mTextPaint);
canvas.drawTextOnPath(str, path, 30, 60, mTextPaint);

1般来说是意义图,注意看图片中的银色部分,高粱红的线是用代码绘制出来的path参考线,影青的箭头是path的品位和垂直方向的走向,结合下图能够更好的知晓drawTextOnPath的hOffset和vOffset参数。

永利网上娱乐 26

  • drawTextOnPath(char[] text, int index, int count, Path path, float
    hOffset, float vOffset, Paint paint)

以此艺术的套路想必不用解释了。

drawTextRun()的重载方法

  • drawTextRun(char[] text, int index, int count, int contextIndex,
    int contextCount, float x, float y, boolean isRtl, Paint paint)
  • drawTextRun(CharSequence text, int start, int end, int contextStart,
    int contextEnd, float x, float y, boolean isRtl, Paint paint)

drawTextRun()可以文字的是从左到右照旧从右到左的各种来绘制,在那之中尾数第三个参数is陆风X8tl便是用来控制方向的,true正是倒序绘制,false正是正序绘制,别的的参数就没啥好说的了,那几个法子用法相比简单,这里就不贴代码了。此外这一个点子是在API
二叁才起来添加的,使用时要留心。

到如今甘休,Canvas的常用用法基本介绍完了,接下去就能够主要来看Paint的利用了,Paint和Canvas两者是不足分离的,两者合营,相得益彰。所以在下边包车型地铁用法示例中难免要用到Canvas的有关办法。

drawTextRun()的重载方法

  • drawTextRun(char[] text, int index, int count, int contextIndex,
    int contextCount, float x, float y, boolean isRtl, Paint paint)
  • drawTextRun(CharSequence text, int start, int end, int contextStart,
    int contextEnd, float x, float y, boolean isRtl, Paint paint)

drawTextRun()能够文字的是从左到右照旧从右到左的1一来绘制,个中尾数第三个参数isPAJEROtl正是用来决定方向的,true正是倒序绘制,false便是正序绘制,其余的参数就没啥好说的了,这些法子用法相比简单,那里就不贴代码了。此外这些办法是在API
二3才开端添加的,使用时要留意。

到近日甘休,Canvas的常用用法基本介绍完了,接下去就足以重点来看Paint的应用了,Paint和Canvas两者是不行分离的,两者合营,相得益彰。所以在底下的用法示例中难免要用到Canvas的相关方法。

采纳Paint衡量文字的尺寸,定位文字

大家在支付自定义控件时,免不了要精明确位文字的文字,例如必须把文字放在有个别区域的正中间,或然必须让壹行文字的几何中央规范的处于有些点上,那时我们假使不懂这里的技法只怕就要盲指标试地点了,那样一点一点试出来的岗位很离谱赖,恐怕换个显示屏尺寸地方就狼狈了,接下去怎么来探望怎么样用最优雅的姿势来规范的定点文字。

实在在档次方向的一定还相比好说,直接动用Paint.setTextAlign()就能化解大多供给,首就算在档次方向上稍稍复杂一点,想要定位地方,首先必要先获得文字的惊人,要用到Paint的以下三个措施:

  • float
    ascent():依照文字大小获取文字顶端到文字基线的偏离(重临的是负值)
  • float
    descent():依照文字大小获取文字尾巴部分到文字基线的偏离(重返的事正值)

有了这么些格局那就不行好办了,首先用代码结合功效图说美素佳儿(Friso)下基线、ascent、descent和文字的涉及:

y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
canvas.drawLine(x - 300, y, x+300, y, mPointPaint);
mTextPaint.setTextAlign(Paint.Align.CENTER);// 水平方向上让文字居中
float ascent = mTextPaint.ascent(); // 根据文字大小获取文字顶端到文字基线的距离(返回的是负值)
float descent = mTextPaint.descent(); // 根据文字大小获取文字底部到文字基线的距离(返回的事正值)
canvas.drawLine(x - 300, y + ascent, x+300, y + ascent, mPointPaint);
canvas.drawLine(x - 300, y + descent, x+300, y + descent, mPointPaint);
canvas.drawText(str, x, y, mTextPaint);

职能图如下,它们中间的涉及注意看图片里面包车型地铁证实。(注:在那里感激园友在截图中建议的1处错误,现已勘误)

永利网上娱乐 27

接下去就让文字的主导落在参考试场点上:

// 将文字的中心定位在参考点上
y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
canvas.drawText(str, x, y - ascent / 2 - descent / 2, mTextPaint);

成效图如下,仔细看参考试场点(红点)和文字的职位:

永利网上娱乐 28

利用Paint度量文字的尺寸,定位文字

我们在支付自定义控件时,免不了要精分明位文字的文字,例如必须把文字放在有些区域的正中间,也许必须让1行文字的几何主题规范的介乎有个别点上,那时我们借使不懂那里的奥妙也许就要盲指标试地方了,那样一点一点试出来的岗位很不可相信,恐怕换个显示屏尺寸地点就难堪了,接下去怎么来看看哪些用最优雅的姿势来规范的定位文字。

实质上在档次方向的平昔还比较好说,直接运用Paint.setTextAlign()就能解决大多急需,首若是在档次方向上稍稍复杂一点,想要定位地方,首先需求先获得文字的中度,要用到Paint的以下多少个点子:

  • float
    ascent():依据文字大小获取文字顶端到文字基线的离开(重返的是负值)
  • float
    descent():依照文字大小获取文字尾巴部分到文字基线的离开(再次回到的事正值)

有了那多少个措施这就分外好办了,首先用代码结合功用图说美素佳儿下基线、ascent、descent和文字的涉及:

y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
canvas.drawLine(x - 300, y, x+300, y, mPointPaint);
mTextPaint.setTextAlign(Paint.Align.CENTER);// 水平方向上让文字居中
float ascent = mTextPaint.ascent(); // 根据文字大小获取文字顶端到文字基线的距离(返回的是负值)
float descent = mTextPaint.descent(); // 根据文字大小获取文字底部到文字基线的距离(返回的事正值)
canvas.drawLine(x - 300, y + ascent, x+300, y + ascent, mPointPaint);
canvas.drawLine(x - 300, y + descent, x+300, y + descent, mPointPaint);
canvas.drawText(str, x, y, mTextPaint);

功用图如下,它们中间的涉及注意看图片里面包车型地铁表达。(注:在此地多谢园友在截图中建议的1处错误,现已纠正)

永利网上娱乐 29

接下去就让文字的为主落在参考点上:

// 将文字的中心定位在参考点上
y += Y_SPACE;
canvas.drawPoint(x, y, mPointPaint);
canvas.drawText(str, x, y - ascent / 2 - descent / 2, mTextPaint);

职能图如下,仔细看参考试场点(红点)和文字的职位:

永利网上娱乐 30

动用Paint.setShader()(着色器)绘制渐变色

利用 setShader()
方法能够添加渐变颜色也足以采取图片作为背景,其参数是三个Shader类,传入差别的Shader子类能够完毕差异的渐变效果照旧添加背景图片,其子类有瞬间两种:

  • LinearGradient:线性渐变
  • RadialGradient:放射状渐变
  • SweepGradient:扫描渐变
  • BitmapShader:添加背景图片
  • ComposeShader:多种Shader组合

上面接个Shader的子类在应用格局上都大约,那里只用LinearGradient为例说美赞臣下,并注意对LinearGradient构造器的结尾一个参数字传送入分裂的参数对应的作用图:

/* Shader 渐变 */
y = 100;
Shader shader = new LinearGradient(x - 50, y - 80, x + 50, y + 80,
        Color.parseColor("#FFCCBB"), Color.parseColor("#FF0000"), Shader.TileMode.CLAMP);
mTextPaint.setShader(shader);
canvas.drawRect(x - 500, y - 80, x + 500, y + 80, mTextPaint);

y += 3 * Y_SPACE;
Shader shader1 = new LinearGradient(x - 50, y - 80, x + 50, y + 80,
        Color.parseColor("#FFCCBB"), Color.parseColor("#FF0000"), Shader.TileMode.REPEAT);
mTextPaint.setShader(shader1);
canvas.drawRect(x - 500, y - 80, x + 500, y + 80, mTextPaint);

y += 3 * Y_SPACE;
Shader shader2 = new LinearGradient(x - 50, y - 80, x + 50, y + 80,
        Color.parseColor("#FFCCBB"), Color.parseColor("#FF0000"), Shader.TileMode.MIRROR);
mTextPaint.setShader(shader2);
canvas.drawRect(x - 500, y - 80, x + 500, y + 80, mTextPaint);

作用图如下:

永利网上娱乐 31

除开上述那么些,Paint的用法还有好多居多,临时半会也列不完,博主在那也不得不投石问路,感兴趣的爱人可查看官方API自行探索。


终极想说的是,本体系小说为博主对Android知识进行重复梳理,查缺补漏的就学进度,1方面是对自身忘记的事物加以复习重新精通,另一方面相信在重新学习的进度中定会有高大的新获得,若是你也有跟自个儿壹样的想法,无妨关怀本人叁头读书,互相研商,共同提高!

参考文献:

运用Paint.setShader()(着色器)绘制渐变色

使用 setShader()
方法能够添加渐变颜色也得以应用图片作为背景,其参数是二个Shader类,传入区别的Shader子类能够完成区别的渐变效果照旧添加背景图片,其子类有眨眼之间间二种:

  • LinearGradient:线性渐变
  • RadialGradient:放射状渐变
  • SweepGradient:扫描渐变
  • BitmapShader:添加背景图片
  • ComposeShader:多种Shader组合

上边接个Shader的子类在采用方法上都大致,那里只用LinearGradient为例说宾博下,并留意对LinearGradient构造器的末尾3个参数字传送入分裂的参数对应的成效图:

/* Shader 渐变 */
y = 100;
Shader shader = new LinearGradient(x - 50, y - 80, x + 50, y + 80,
        Color.parseColor("#FFCCBB"), Color.parseColor("#FF0000"), Shader.TileMode.CLAMP);
mTextPaint.setShader(shader);
canvas.drawRect(x - 500, y - 80, x + 500, y + 80, mTextPaint);

y += 3 * Y_SPACE;
Shader shader1 = new LinearGradient(x - 50, y - 80, x + 50, y + 80,
        Color.parseColor("#FFCCBB"), Color.parseColor("#FF0000"), Shader.TileMode.REPEAT);
mTextPaint.setShader(shader1);
canvas.drawRect(x - 500, y - 80, x + 500, y + 80, mTextPaint);

y += 3 * Y_SPACE;
Shader shader2 = new LinearGradient(x - 50, y - 80, x + 50, y + 80,
        Color.parseColor("#FFCCBB"), Color.parseColor("#FF0000"), Shader.TileMode.MIRROR);
mTextPaint.setShader(shader2);
canvas.drawRect(x - 500, y - 80, x + 500, y + 80, mTextPaint);

效果图如下:

永利网上娱乐 32

除了上述这一个,Paint的用法还有为数不少广大,近年来半会也列不完,博主在那也只可以投砾引珠,感兴趣的情侣可查看官方API自行探索。


末了想说的是,本种类小说为博主对Android知识进行再度梳理,查缺补漏的求学进程,一方面是对友好忘记的事物加以复习重新通晓,另1方面相信在重新学习的进度中定会有大侠的新收获,固然你也有跟本人同样的想法,无妨关怀自作者一起上学,互相研商,共同提高!

参考文献:

相关文章