自定义View知识体系

来源:互联网 发布:阿里云自定义监控 编辑:程序博客网 时间:2024/06/01 07:47

自定义View简介

在Android原生控件无法满足需求的情况下,但是又需要实现一些特殊效果的时候该怎么办呢?这个时候就可以通过自定义View去实现。因此自定义View是对于Android工程师来说无疑是比较重要的技能。今天我会针对自定义View的一些知识作讲解,水平有限,不对的地方望批评交流。

自定义View分类

自定义View本质上其实就是通过Java的继承特性去扩展特定需求,且大家都知道Android中的控件可以大体上分为View与ViewGroup(注意ViewGroup本质上也是View)。例如:TextView是通过继承View实现,LinearLayout是通过继承ViewGroup实现。那么自定义View的话,肯定是可以直接通过继承View或者ViewGroup去实现。但是一般情况下优先考虑继承已经控件去实现自定义View,那么就有以下几种分类:

1.继承View
这种方式主要用来实现一些不规则效果,即通过onDraw绘制控件内容,并且如果有交互需求的话,通过onTouchEvent方法去处理触摸事件。例如:QQ的小红点

注意问题:需自行支持wrap_content与padding

2.继承特定的View
这种方式一般用于扩展已有View的功能,根据需要覆写相关的方法,重写逻辑。例如:自定义View继承TextView实现图文混排控件

3.继承ViewGroup
这种方式侧重于控件元素的布局排列,线性布局采用的是现行排列控件,相对布局采用的是相对方式排列控件。那么假设我们需要特定的排列规则系统并没有提供控件,我们就可以通过自定View继承ViewGroup实现。作为ViewGroup,其他核心实现就是控件的测量onMeasure、控件排列规则onLayout。

4.继承特定的ViewGroup
这种方式倾向于用某种排列方式组合特定的子控件,例如咱们可以通过继承线性布局并且向其中添加一定数量的子元素水平均匀分布作为主页面的底部选择控件。

自定义View知识点整理

1.View的工作原理
理解View的三大流程
参考:View的工作原理

2.View的事件体系
包括View的位置参数与View的触摸事件流程,即事件分发机制
参考:View的事件体系

3.动画相关
View动画Animation:包括补间动画与帧动画
属性动画:ObjectAnimator、ValueAnimator
贝塞尔曲线:Path#quadTo()和Path#cubicTo()
属性动画的插值器TimeInterpolator与估值器TypeEvaluator

4.画布Canvas
绘制颜色 drawColor, drawRGB, drawARGB
绘制基本形状 drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc
绘制图片 drawBitmap, drawPicture
绘制文本 drawText, drawPosText, drawTextOnPath
绘制路径 drawPath 绘制贝塞尔曲线时也需要用到该函数
顶点操作 drawVertices, drawBitmapMesh 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用
画布剪裁 clipPath, clipRect 设置画布的显示区域
画布快照 save, restore, saveLayerXxx, restoreToCount, getSaveCount 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数
画布变换 translate, scale, rotate, skew 依次为 位移、缩放、 旋转、错切
Matrix(矩阵) getMatrix, setMatrix, concat 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。

5.Paint
ColorMatrix setColorFilter 颜色矩阵 滤镜效果
setXfermode 图形混合模式

6.Shader
BitmapShader 类:位图渲染器
LinearGradient 类:线性渐变
RadialGradient 类:放射渐变
SweepGradient 类:扫射渐变
ComposeShader 类:组合渲染器

6.Path
addArc(RectF oval, float startAngle, float sweepAngle)
绘制弧线,配合Paint的Style可以实现不同的填充效果
addCircle(float x, float y, float radius, Path.Direction dir)
绘制圆形,其中第dir参数用来指定绘制时是顺时针还是逆时针
addOval(RectF oval, Path.Direction dir)
绘制椭圆形,其中 oval作为椭圆的外切矩形区域
addRect(RectF rect, Path.Direction dir)
绘制矩形
addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
绘制圆角矩形
lineTo(float x, float y)
绘制直线
addPath(Path src)
添加一个新的Path到当前Path
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
与addArc方法相似,但也有区别,下文细述。
quadTo(float x1, float y1, float x2, float y2)
绘制二次贝塞尔曲线,其中 (x1,y1)为控制点,(x2,y2)为终点
cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
绘制三次贝塞尔曲线,其中(x1,y1),(x2,y2)为控制点,(x3,y3)为终点

r开头的方法是基于当前绘制开始点的offest,比如当前paint位于 (100,100)处,则使用rLineTo(100,100)方法绘制出来的直线是从(100,100)到(200,200)的一条直接,由此可见rXXX方法方便用来基于之前的绘制作连续绘制

Path.op方法
此方法用于对两个Path对象做相应的运算组合(combine)

6.PathMeasure
解析Path对象并可截取片段,通过这个类可以实现路径动画效果
路径动画

自定义View整体流程

1.需求分析:分析你所需要实现的自定义控件的效果,包括UI效果与用户交互效果
2.实现方式:选择自定义控件的方式,根据自定义View的效果选择合适的方式实现。首先确定该自定义控件是属于组合类或者偏向于效果交互类,选择继承View或者ViewGroup。再者考虑是否可基于现有系统原生控件进行修改扩展实现
3.代码实现:自定义属性attr、初始化(Path、Paint、Canvas缓存、控件属性、相关逻辑变量等)、测量onMeasure、布局onLayout、界面绘制onDraw。如果有用户交互的话,则在onTouchEvent中实现交互逻辑