有机会拜读启舰老师的自定义view,学习颇多
-
就像平时一样画图需要纸和笔
- android中Paint类就是画笔,而Canvas类就是纸(画布)
- 所以可以得知
- 笔的属性就是在paint类中设置
- 画出的形状就会在 canvas中进行绘制
-
首先实现一个自定义动画–画圆:
package com.example.adminstator.myviewdesign.PaintBasic;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* Created with Android Studio.
* Description:
* User: wjx
* Date: 2019-04-29
* Time: 20:44
*/
public class BasicView extends View {
public BasicView(Context context){
super(context);
}
public BasicView(Context context, AttributeSet attributeSet){
super(context, attributeSet);
}
public BasicView(Context context, AttributeSet attributeSet, int defStyle){
super(context, attributeSet, defStyle);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//设置画笔的基本属性
Paint paint = new Paint();
paint.setColor(Color.RED);//笔迹为红色
paint.setStyle(Paint.Style.STROKE);//设置为笔刷
paint.setStrokeWidth(50);//笔粗为50
//画一个圆
canvas.drawCircle(190, 200, 150, paint);
}
}
- 在主布局文件中引入
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.adminstator.myviewdesign.PaintBasic.BasicView
android:layout_height="match_parent"
android:layout_width="match_parent"/>
</LinearLayout>
-
实现效果:
-
画笔的属性设置:
- setColor()
void setColor(int color)
一种颜色是由红、绿、蓝三色合成出来的,所以参数color只能取8位的 0xAARRGGBB 样式颜色值
A:代表透明度(Alpha) 取值范围为0~255(对应16进制为0x00~0xFF), 取值越小透明度越高,图像也就越透明,当取值0时,完全透明
R: 代表红色值 取值范围为0~255(对应16进制为0x00~0xFF), 取值越小红色越少,当取值0时,红色完全不可见
G: 代表绿色值 取值范围为0~255(对应16进制为0x00~0xFF), 取值越小绿色越少,当取值0时,绿色完全不可见
B: 代表蓝色值 取值范围为0~255(对应16进制为0x00~0xFF), 取值越小蓝色越少,当取值0时,蓝色完全不可见
* setStyle()
void setStyle(Style style)
该函数设置填充样式,对于文字和集合图形都有效,style的取值如下
Paint.Style.FILL: 仅填充内部
Paint.Style.FILL_AND_STROKE: 填充内部和描边
Paint.Style.STROKE:仅描边
* setStokeWidth()
void setStrokeWidth(float width)
用于设置描边的宽度值,单位是px, 当画笔的style样式是STROKE 、FILL_AND_STROKE时有效
- Canvas使用基础:
void drawColor(itn color)
void drawARGB(int a, int r, int g, int b)
void drawRGB(int r, int g, int b)
其中
1.drawColor()函数中参数color的取值必须是8位的0xAARRGGBB样式颜色值。
2.drawARGB()函数允许分别传入A,R,G,B分量,每个颜色值的取值范围都是0~255(对应16进制),内部会通过这些颜色分量构造出对应的颜色值。
3.drawRGB()函数只允许传入R,G,B分量,透明度Alpha取值为255.
- 画直线:
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
参数:
* startX 起始点X坐标
* startY 起始点Y坐标
* stopX 终点X的坐标
* stopY 终点Y的坐标
canvas.drawLine(100, 100, 200, 200, paint);
- 画点:
void drawPoint(float x , float y, Paint paint)
参数:
* float x: 点的x坐标
* float y: 点的y坐标
canvas.draw(100, 100, paint);
- 矩形工具类 RectF、 Rect:
上述两个类都是 矩形类,根据四个点描绘出矩形结构
RectF和Rect中的类和方法完全相同,唯一不同是RectF是用来保存float类型的矩形结构的,而Rect是用来保存int类型的矩形结构的
RectF的构造函数:
RectF()
RectF(float left, float top, float right, float bottom)
RectF(RectF r)
RectF(Rect r)
Rect构造函数:
Rect()
Rect(int left, int top, int right, int bottom)
Rect(Rect r)
eg:
(1)Rect rect = new Rect(10, 10, 100, 100);
(2) Rect rect = new Rect()
rect.set(10, 10, 100, 100)
- 矩形绘制方法:
void drawRect(float left, float top ,float right, float bottom, Paint paint)
void drawRect(RectF rect, Paint paint)
void drawRect(Rect r, Paint paint)
canvas.drawRect(10, 10, 100, 100 paint)
RectF rectf = new REctF(210f, 10f, 300f, 100f);
canvas.drawRect(rectf, paint)
- 颜色:
(1)可以使用Color.XXX来使用相应的颜色
(2)构造颜色:
* 带有透明度的颜色:
static int argb(int alpha, int red, int green, int blue)
eg:
public static int argb(int alpha, int red, int green, int blue){
return (alpha<<24 | (red<<16) | (green << 8) | blue;
}
(3) 不带透明度的颜色:
static int rgb(int red, int green, int blue)
(4)提取颜色分量:
static int alpha(int color)
static int red(int color)
static int green(int color)
static int blue(int color)
int green = Color.green(0xFF000F00)
- 在Android中,Path类代表路径:
void drawPath(Path path, Paint paint);
- 直线路径:
画一条直线路径,一般涉及下面三个函数
void moveTo(float x1, float y1); //(x1, y1) 是直线的起始点,即将直线路径的绘制点定在(x1, y1)的位置
void lineTo(float x2, float y2); //(x2, y2)是直线的终点。又是下一次绘制直线路径的起始点;lineTo()函数可以一直使用
void close(); //如果连续画几条直线,那么调用close()使得直线首尾链接形成闭环
eg:
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
Path path = new Path();path.moveTo(10,10);
path.lineTo(10,100);
path.lineTo(300, 100);
path.close();
canvas.drawPath(path, paint);
- 弧线路径:
void arcTo(RectF oval, float startAngle, float sweepAngle);
参数:
RectF oval:生成椭圆的矩形
float startAngle: 弧开始的角度,以X轴正方向为0度
float sweepAngle: 弧持续的角度
默认情况下路径都是连续的,除非:
* 调用addXXX系列函数,将直接添加固定形状的路径
* 调用moveTo()函数改变绘制起始位置
或者重载arcTo()的两个方法
void arcTo(float left, float top, floet right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)
void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
参数:
forceMoveTo: 是否强制地将弧的起始点作为绘制起始位置
-
Region区域:
- Region本意并不是用来绘图的
构造Region:
* 直接构造:
public Region(Region region);//复制一个Region的范围
public Region(Rect r); //创建一个矩形区域
public Region(int left, int top, int right, int bottom); //创建一个矩形区域
间接构造:
public Region()
public void setEmpty() //置空,将原来的区域变成一个空变量
public boolean set(Region region) //利用新区域 替换原来的区域
public boolean set(Rect r) //利用矩形所代表的区域来替代其他区域
public boolean set(int left, int top, int right, int bottom) //根据矩形的两个焦点构造出矩形区域来替换原来的区域
public boolean setPath(Path path, Region clip) //根据路径的区域与某区域的交集构造出新的区域
eg:
package com.example.adminstator.myviewdesign.PaintBasic;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.RegionIterator;
import android.util.AttributeSet;
import android.view.View;
/**
* Created with Android Studio.
* Description:
* User: wjx
* Date: 2019-04-29
* Time: 20:44
*/
public class BasicView extends View {
public BasicView(Context context){
super(context);
}
public BasicView(Context context, AttributeSet attributeSet){
super(context, attributeSet);
}
public BasicView(Context context, AttributeSet attributeSet, int defStyle){
super(context, attributeSet, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
//构造一条椭圆路径
Path path = new Path();
RectF rectF = new RectF(50, 50, 200, 500);
path.addOval(rectF, Path.Direction.CCW);
Region region = new Region();
region.setPath(path, new Region(50, 50,200, 200));
drawRegion(canvas, region, paint);
}
private void drawRegion(Canvas canvas, Region region, Paint paint){
RegionIterator regionIterator = new RegionIterator(region);
Rect r = new Rect();
while (regionIterator.next(r)){
canvas.drawRect(r, paint);
}
}
}