一、构造函数
共有4个,自定义View必须重写至少一个构造函数
public class MyView extends View {
/**
* 在java代码里new的时候会用到
* @param context
*/
public MyView(Context context) {
super(context);
}
/**
* 在xml布局文件中使用时自动调用
* @param context
* @param attrs
*/
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
/**
* 不会自动调用,如果有默认style时,在第二个构造函数中调用
* @param context
* @param attrs
* @param defStyleAttr
*/
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 只有在API版本>21时才会用到
* 不会自动调用,如果有默认style时,在第二个构造函数中调用
* @param context
* @param attrs
* @param defStyleAttr
* @param defStyleRes
*/
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
二、常用控件
1、Paint类——画笔
Paint类代表画笔,用来描述图形的颜色和风格,如线宽,颜色,透明度,和填充效果等信息,使用Paint时,需要先创建该类的对象,这可以通过该类提供的构造方法来实现。通常情况下,只需要使用无参数的构造方法来创建一个使用默认设置的Paint对象:
Paint paint = new Paint();
常用方法 | 方法说明 |
---|---|
setARGB(int a, int r, int g, int b) | 用于设置颜色,各参数值均为0~255之间的整数 |
setColor(int color) | 用于设置颜色 |
setAlpha(int a) | 用于设置透明度,值为0~255之间的整数 |
setAntiAlias(boolean aa) | 用于指定是否使用抗锯齿功能,如果使用会使绘图速度变慢 |
setDither(boolean dither) | 用于指定是否使用图像抖动处理,如果使用会使图像颜色更加平滑和饱满,更加清晰 |
setPathEffect(PathEffect effect) | 用于设置绘制路径时的路径效果,例如点画线 |
setShader(Shader shader) | 用于设置渐变,可以使用LinearGradient(线性渐变)、RadialGradient(径向渐变)或者SweepGradient(角度渐变)。 TileMode.REPEAT:重复的 TileMode.CLAMP:固定的–渐变过去 TileMode.MIRROR:镜像的,对称的 |
setStrokeCap(Cap cap) | 用于当画笔的填充样式为STROKE或FILL_AND_STROKE时,设置笔刷的图形样式。 参数值可以是Cap.BUTT、Cap.ROUND或Cap.SQUARE。 主要体现在线的端点上 |
setStrokeJoin(Join join) | 用于设置画笔转弯处的连接风格 参数值为Join.BEVEL、Join.MITER或Join.ROUND |
setStrokeWidth(float width) | 用于设置笔触的宽度 |
setStyle(Style style) | 用于设置填充风格 参数值为Style.FILL、Style.FILL_AND_STROKE或Style.STROKE |
setTextAlign(Align align) | 设置字文本的排列方式 |
setTextSize(float textSize) | 用于设置字体大小 |
setFakeBoldText(boolean fakeBoldText) | 用于设置是否为粗体文字 |
2、Canvas类——画布
Android提供了强大的二维图形库,比较常用的是绘制几何图形,绘制文本,路径和图片等
比较常见的图形包括点,线,弧,圆形,矩形,在Android中,Canvas类提供了丰富的绘制几何图形的方法,通过这些方法可以绘制出各种几何图形
常用方法 | 方法说明 |
---|---|
drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, Paint paint) | 绘制圆弧 left:圆左侧的X坐标。必须确保left<=right top:圆顶部的Y坐标。必须确保top<=bottom right:圆右侧的X坐标 bottom:圆底部的Y坐标 startAngle:弧的起始角度。负数或大于或等于360则对360模除(水平方向为0度) sweepAngle:顺时针扫描的角度。大于或等于360则画成圆 useCenter:是否显示半径连线,true表示显示圆弧与圆心的半径连线,false表示不显示 paint:绘制时所使用的画笔 |
drawCircle(float cx, float cy, float radius, Paint paint) | 绘制圆 cx,cy:所画圆的中心坐标 radius:圆的半径 |
drawLine(float startX, float startY, float stopX, float stopY, Paint paint) | 绘制一条线 前四个参数为直线的起点和终点的 XY 轴坐标 |
drawLines(float[] pts, Paint paint) | 绘制多条线 pts:待画的坐标点数组,格式为(x1,y1,x2,y2,…),至少4个值 |
drawLines(float[] pts, int offset, int count, Paint paint) | 绘制多条线 pts:待画的坐标点数组,格式为(x1,y1,x2,y2,…),至少4个值 offset:要跳过坐标点数组中几个值才开始画(必须是4的倍数) count:至少为2,offset 之后数组的大小。 |
drawOval(float left, float top, float right, float bottom, Paint paint) | 绘制椭圆 |
drawPoint(float x, float y, Paint paint) | 绘制一个点 |
drawPoints(float[] pts, Paint paint) | 绘制多个点 pts:待画的坐标点数组,格式为(x,y,…),至少2个值 |
drawRect(float left, float top, float right, float bottom, Paint paint) | 绘制矩形 |
drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, Paint paint) | 绘制圆角矩形 rx,ry 表示 left 到 left+rx 与 left 到 left+ry 所围区域做弧 |
scale(float sx, float sy) | sx和sy用于指定x轴和轴y轴的缩放比例,默认做左上角开始缩放 |
scale(float sx, float sy, float px, float py) | px 和py是以它们为轴心进行缩放 |
rotate(float degrees) | 参数用于指定旋转的角度,默认做左上角开始旋转 |
rotate(float degrees, float px, float py) | px py为旋转的轴心 |
translate(float dx, float dy) | dx和dy用于指定移动到的位置的x和y的坐标距离 |
skew(float sx, float sy) | sx和sy用于指定x轴和轴y轴的倾斜量,默认做左上角开始倾斜 |
save() | 保存画布,这句代码之前的图像不会被特效影响 |
restore() | 恢复画布到canvas.save()之前的状态 |
注意:画布一旦经过特效处理,比如旋转、缩放等,那么之后所绘制的图像都是旋转过后的。
三、常用方法
1、onMeasure(int widthMeasureSpec, int heightMeasureSpec)
测量控件的宽和高
1)MeasureSpec
MeasureSpec是View的内部类,它封装了一个View的尺寸,在onMeasure()当中会根据这个MeasureSpec的值来确定View的宽高。
MeasureSpec的值保存在一个int值当中。一个int值有32位,前两位表示模式mode,后30位表示大小size。即MeasureSpec = mode(高2位) + size(低30位)。
在MeasureSpec当中一共存在三种mode:UNSPECIFIED、EXACTLY 和AT_MOST
模式 | 描述 |
---|---|
UNSPECIFIED | 无限制,View对尺寸没有任何限制,View设置为多大就应当为多大。此种模式比较少见 |
EXACTLY | 精准模式,View需要一个精确值,这个值即为MeasureSpec当中的Size,对应match_parent |
AT_MOST | 最大模式,View的尺寸有一个最大值,View不可以超过MeasureSpec当中的Size值,对应wrap_content |
2、onLayout(boolean changed, int left, int top, int right, int bottom)
- 用来改变View的(在父控件的)位置
3、onDraw(Canvas canvas)
所有 View类都包含了一个 onDraw(Canvas c)方法,这个方法的作⽤就是绘制View自身
- invalidate()
onDraw方法在View初始化的时候会调用一次,之后,只要在代码中调用invalidate()方法,onDraw方法就会被调用一次,重新绘制自己。简称“重绘自己” - postInvalidateDelayed(long delayMilliseconds)
每隔delayMilliseconds 毫秒重绘View
四、自定义属性
Android系统的控件以android开头的(比如android:layout_width)都是系统自带的属性。为了方便配置自定义控件的属性,我们也可以自定义属性。
1、自定义属性步骤
- 步骤一:在values目录下创建 attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyView">
<attr name="background_view" format="color" />
</declare-styleable>
</resources>
- 步骤二:布局文件中使用自定义的属性
<com.android.myview.MyView
android:layout_width="wrap_content"
android:layout_height="300dp"
android:layout_gravity="center"
app:background_view="#FF00FF"/>
- 步骤三:在View的构造方法中获取TypedArray并设置该自定义属性的用途
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyView);
int color = typedArray.getColor(R.styleable.MyView_background_view, Color.BLACK);
//比如该自定义属性设置为背景
setBackgroundColor(color);
//获取资源后要及时回收
typedArray.recycle();
}
2、属性值的类型format
1)reference:参考某一资源ID
- 属性定义
<attr name = "background" format = "reference" />
- 属性使用
<ImageView android:background = "@drawable/图片ID" />
2)color:颜色值
- 属性定义
<attr name = "textColor" format = "color" />
- 属性使用
<TextView android:textColor = "#00FF00" />
3)boolean:布尔值
- 属性定义
<attr name = "focusable" format = "boolean" />
- 属性使用
<Button android:focusable = "true" />
4)dimension:尺寸值
- 属性定义
<attr name = "layout_width" format = "dimension" />
- 属性使用
<Button android:layout_width = "42dip" />
5)float:浮点值
- 属性定义
<attr name = "fromAlpha" format = "float" />
- 属性使用
<alpha android:fromAlpha = "1.0" />
6)integer:整型值
- 属性定义
<attr name = "framesCount" format="integer" />
- 属性使用
<animated-rotate android:framesCount = "12" />
7)string:字符串
- 属性定义
<attr name = "text" format = "string" />
- 属性使用
<TextView android:text = "我是文本" />
8)fraction:百分数
- 属性定义
<attr name = "pivotX" format = "fraction" />
- 属性使用
<rotate android:pivotX = "200%" />
9)enum:枚举值
- 属性定义
<declare-styleable name="名称">
<attr name="orientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
</declare-styleable>
- 属性使用
<LinearLayout
android:orientation = "vertical">
</LinearLayout>
注意:枚举类型的属性在使用的过程中只能同时使用其中一个,不能 android:orientation = “horizontal|vertical"
10)flag:位或运算
- 属性定义
<declare-styleable name="名称">
<attr name="gravity">
<flag name="top" value="0x01" />
<flag name="bottom" value="0x02" />
<flag name="left" value="0x04" />
<flag name="right" value="0x08" />
<flag name="center_vertical" value="0x16" />
...
</attr>
</declare-styleable>
- 属性使用
<TextView android:gravity="bottom|left"/>
注意:位运算类型的属性在使用的过程中可以使用多个值
11)混合类型:属性定义时可以指定多种类型值
- 属性定义
<declare-styleable name = "名称">
<attr name = "background" format = "reference|color" />
</declare-styleable>
- 属性使用
<ImageView
android:background = "@drawable/图片ID" />
或者:
<ImageView
android:background = "#00FF00" />