侧边栏壁纸
博主头像
爱探索

行动起来,活在当下

  • 累计撰写 42 篇文章
  • 累计创建 11 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

android-自定义控件基础(一)

jelly
2024-07-05 / 0 评论 / 0 点赞 / 49 阅读 / 0 字

自定义控件基础

1. 概述

在Android中绘图主要用两个类 Paint,Canvas。Paint就相当与我们平时画画的画笔,Canvas就相当于纸这里叫画布

2. Paint类画笔的基本设置

2.1. 设置颜色

setColor(int color)

参数color有8位十六进制数组成例如:0xFFFFFFFF,对应着颜色位ARGB)

其中:例如红色:0xFFFF0000

A表示透明度取值范围0x00-0xFF
R表示红色取值范围0x00-0xFF
G表示绿色取值范围0x00-0xFF
B表示蓝色取值范围0x00-0xFF

2.2. 设置填充样式

setStyle(Style style);

该函数用于设置填充样式,对于文字几何图形都有效,

style取值范围:

  • Paint.Style .FILL :将填充使用此样式绘制的几何和文本,忽略绘画中与笔划相关的所有设置。
  • Paint.Style.FILL_AND_STROKE 使用此样式绘制的几何和文本将同时填充和描边,尊重绘画中与笔划相关的字段。
  • Paint.Style.STROKE 使用此样式绘制的几何和文本将被描边,尊重绘画上与笔划相关的字段。

2.3. 设置画笔宽度

setStrokeWidth(float width) 此函数用于设置画笔宽度单位dp

关于Paint详细api:http://www.android-doc.com/reference/android/graphics/Paint.html

3. Canvas的使用基础

3.1.画布背景的设置

设置画布背景有3中方法

  • void drawColor(int color)
  • void drawARGB(int a,int r,int g,int b)
  • void drawRGB(int r,int b,int c)

使用drawColor时参数时8位十六进制数0xFFFFFFFF对应AARRGGBB

第二个参数分别对应ARGB,第三个同第二个只是少了透明度

3.2. 画直线

drawLine(float startX, float startY, float stopX, float stopY, Paint paint)

  • startX:起点X坐标
  • startY:起点Y坐标
  • stopX:终点X坐标
  • stopY:终点Y坐标
  • paint 画笔

    //设置画笔
    Paint paint=new Paint();
    paint.setColor(Color.RED);//画笔设置为红色
    paint.setStyle(Paint.Style.FILL_AND_STROKE);

    //绘制
    canvas.drawLine(100.100,200,200,paint);
    drawPoint 绘制点

    //设置画笔 
    Paint paint=new Paint();
    paint.setColor(Color.RED);//画笔设置为红色
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    //绘制
    canvas.drawPaint(200,200,paint);
 

3.3. 矩形工具类

RectF,Rect

RectF为一个矩形保存四个浮点坐标。矩形由其4条边(左,上,右下)的坐标表示。可以直接访问这些字段。使用width()和height()来检索矩形的宽度和高度。注意:大多数方法都不检查坐标是否正确排序(即左<=右和顶<=底)

3.3.1. RectF构造函数

  • public RectF();创建一个新的空RectF。所有坐标初始化为0
  • public RectF(float left, float top, float right, float bottom);创建一个具有指定坐标的新矩形。(最常用到的)
  • public RectF(RectF r);创建一个新矩形,用指定的值初始化 矩形(未修改)。
  • public RectF(Rect r)

3.3.2. Rect构造函数

  • public Rect();创建一个新的空RectF。所有坐标初始化为0
  • public Rect(int left, inttop, int right, int bottom);创建一个具有指定坐标的新矩形。(最常用到的)
  • public Rect(Rect r);创建一个新矩形,用指定的值初始化 矩形(未修改)。
    由构造函数看以看出RectF与Rect基本相同,不同的只是RectF保存的时float Rect保存的是int

就一般而言要构造一个矩形结构使用一下两种方式实现


//方法一
Rect rect=new Rect(20,20,100,100);
//方法二
Rect rect=new Rect();
rect.set(20,20,100,100);

3.4. 绘制矩形

先看看绘制矩形的方法

  • void drawRect(float left, float top, float right, float bottom,Paint paint);
  • void drawRect(Rect r);
  • void drawRectF(RectF r);
    通过这个可以看出 绘制矩形可以直接绘制RectF或Rect构造出来的矩形结构

例:


Paint paint=new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);//抗锯齿
paint.setStyle(Paint.Style.STROKE);

//直接绘制
canvas.drawRect(0, 0, 100, 100, paint);

//间接绘制
RectF r=new RectF(0, 0, 100, 100);
canvas.drawRect(r,paint);
 

当然在绘制中还有很多方法但是都大同小异 所有绘制方法api:http://www.android-doc.com/reference/android/graphics/Canvas.html

4. 路径(Path类)

路径是个比较重要的概念比如在现实生活中我们画画都是通过一条一条线段组成的,在android绘图中一样也可以通过一段一段的线段组成复杂的图形

在android中Path就表示路径

4.1. 直线路径

构造的函数

  • void moveTo(float x1,float x2);//在这里x1,x2为起点

  • void lineTo(float x1,float x2);//x1,x2为终点

  • void close();//如果绘制多条直线没有形成闭环 调用此函数可以使首位相连形成闭环


/**
*绘制一个三角形
*/
Path path = new Path();‘

path.moveTo(100, 100);
path.lineTo(200, 100);
path.lineTo(100, 200);
path.close();//形成闭环
canvas.drawPath(path,paint);

4.2. 绘制弧线路径

  • public void addArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle);

参数说明:
float left, float top, float right, float bottom 左上角坐标 右下角左边

startAngle:弧度开始角度 (360)

sweepAngle:弧度持续角度(360)顺时针

例:


//width 屏幕宽度 height屏幕高度
Path path = new Path();
path.moveTo(width / 2, height / 2);
path.addArc(width / 4, height / 4, width / 4 * 3, height / 4 * 3, 0, 90);
path.close();
canvas.drawPath(path, paint);


5. 区域

5.1. 构造函数

  • public Region() //创建一个空区域
  • public Region(Region region)//辅助一个区域
  • Region(Rect r) 创建一个矩形区域(常用)
  • public Region(int left, int top, int right, int bottom) //创建一个矩形区域(常用)

5.2. Canvas是没有提供对Region的绘制的

例:


 Paint paint=new Paint();
 paint.setColor(Color.RED);
 paint.setStrokeWidth(10);
 paint.setAntiAlias(true);//抗锯齿
 paint.setStyle(Paint.Style.STROKE);
 
 Region region = new Region(width / 4, height / 4, width / 4 * 3, height / 4 * 3);

到这里会发现Canvas中没有方法是对Region绘制的 所以到了这里自己要实现对Region


private void drawRegion(Region region) {
        RegionIterator iterator = new RegionIterator(region);
        Rect rect = new Rect();
        while (iterator.next(rect)) {
            canvas.drawRect(rect, paint);
        }
    }
 

5.3. 间接构造(区域相交)

间接构造是主要通过public Region()的共构造函数与set系列函数实现
详细api :http://www.android-doc.com/reference/android/graphics/Region.html

主要介绍一下
Region.setPath(Path path,Region clip);根据路径区域与某块区域的交集构造出新区域
参数:path 构造区域路径
   clip 与前面的path构成的路径取交集并将交集是设置为最终区域
因为路径可以有很多中构造方法,可以轻而易举的构造出非矩形图形,因而摆脱了只能构造矩形的限制,但是这里需要指定另一个区域取交集,所以要显示完整的路径图像可以创意个比path大的多的区域
如果要实现部分可以通过传入的区域对其限制

示例:


Path path = new Path();
RectF rectF = new RectF(width / 4, height / 4, width / 4 * 3, height / 4 * 3);
path.addOval(rectF, Path.Direction.CCW);//绘制一个椭圆Path.Direction.CCW 表示逆时钟绘制
Region region = new Region(); region.setPath(path, new Region(width / 4, height / 4, width / 4 * 3, height / 4 * 2));//取其交集 
drawRegion(region);//绘制

蓝色为相交的矩形区域 拥塞为原椭圆与矩形相交就形成下图

相交示例1

由此可以看出Region的主要职责不在于绘图,而在于区域相交

相交示例2

当然有区域相交(交集)那当眼也就会有区域相并(并集)

  1. 区域相并

union()函数

上代码看效果


Region region=new Region(width / 4, height / 4, width / 4 * 3, height / 4 * 3);
region.union(new Rect(width / 4, height / 4, width / 4 * 2, height / 4 * 6));
drawRegion(region);

相并示例1

![相并示例2]/upload/%E7%BB%98%E5%9B%BE%E7%9B%B8%E5%B9%B6%E7%A4%BA%E4%BE%8B1.png)

相并了之后的效果

处了相交相并Region还提供了几个跟价灵活的函数

系列函数:

  • op(Rect r,op)

  • op(int left, int top, int right, int bottom,op)

  • op(Region,op)

Op属性:

  • Region.Op .DIFFERENCE 最终区域region1与region2不同的区域
  • Region.Op .INTERSECT 最终区域region1与region2相交的区域
  • Region.Op .REPLACE 最终区域region1与region2region2的区域
  • Region.Op .REVERSE_DIFFERENCE 最终区域region1与region2不同的区域
  • Region.Op .UNION 最终区域region1与region2组合在一起的区域
  • Region.Op.XOR 最终区域region1与region2相交之外的区域

示例


    Rect rect1 = new Rect(100, 100, 400, 200);
    Rect rect2 = new Rect(200, 0, 300, 300);
    //绘制
    canvas.drawRect(rect1, paint);
    canvas.drawRect(rect2, paint);
           
    paint.setStyle(Paint.Style.FILL);
    //使用Op对两个矩形进行相交
    Region region1 = new Region(rect1);
    Region region2 = new Region(rect2);
    region1.op(region2, Region.Op.INTERSECT);
    drawRegion(region1);

6. 重置路径

当我梦需要绘制一条全新的路径是,android为了重复利用控件,允许我们重置路径对象。路径一旦被重置其中保存的所有路径就将被清空,这样我们就不需要重新定义一个路径对象了。重新定义路径对象的问题在于老对象的回收和新对象的内存分配。

重置路径由两个方法

  • void reset()
  • rewind()

这两个函数的共同点都会清空内部所有保存的所有路径,单二者又有区别

0

评论区