自定义View介绍及自定义属性

本文介绍了自定义View的相关知识,包括构造函数、常用控件如Paint和Canvas的使用,以及如何在自定义View中进行测量、布局和绘制。详细讲解了onMeasure()、onLayout()和onDraw()方法,并探讨了自定义属性的步骤和不同类型的属性值,如reference、color、boolean等。
摘要由CSDN通过智能技术生成

一、构造函数

共有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" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值