主要参考文章:
https://www.jianshu.com/p/705a6cb6bfee
本篇主要是对这个主要参考文章的一些理解总结和补充
阅读前请先看完这个参考文章
扩展学习:https://blog.csdn.net/harvic880925/article/details/50995268
1.关于Canvas
和Paint
的补充点:
在onDraw()中绘制View的内容,使用到了两个Canvas
,Paint
的对象,这里Paint
相当于画笔,通常一个自定义View只需要一个画笔对象就可以完成所有绘制工作,Canvas
相当于画布,或则说拿笔的手
@Override
protected void onDraw(Canvas canvas) {
//先执行我们想要画出的内容 避免覆盖原本应该画出的字符串
//这里直接是画在了 View内 没有考虑padding的情况
int width = getWidth();
int height = getHeight();
//画个灰圆
mPaint.setColor(Color.GRAY);
canvas.drawCircle(width/2,height/2,height/2,mPaint);
//画条黑线
mPaint.setColor(Color.BLACK);
canvas.drawLine(0,height/2,width,height/2,mPaint);
//然后执行TextView原本的onDraw,最后画的在最上层
super.onDraw(canvas);
}
效果图:
image.png
PS:按代码执行顺序,后画的会覆盖先画的,比如如果我这里把原本的TextView的绘制方法
super.onDraw(canvas);
放在最前边执行,则绘制的文字会被后边绘制的圆所覆盖一部分
Paint
画笔的常用方法
setARGB
设置颜色
setColor
设置颜色
setAlpha
设置透明度
setAntiAlias
设置是否抗锯齿
setShader
设置画笔的填充效果
setShadowLayer
设置阴影
setStyle
设置画笔风格
setStrokeWidth
设置空心边框的宽度
setTextSize
设置绘制文本时文字的大小
Canvas
画手常用方法:
drawArc
绘制弧参考:https://www.cnblogs.com/huyang011/p/9551576.html
drawBitmap
绘制位图
drawCircle
绘制圆形
drawLine
绘制线
drawOval
绘制椭圆
drawPoint
绘制一个点
drawPoints
绘制多个点
drawRect
绘制矩形
drawRoundRect
绘制圆角矩形
drawText
绘制字符串
drawTextOnPath
沿着路径绘制字符串
drawPath
绘制自定义图像(* 很重要 *)
掌握更多Paint&Canvas&Path的使用可以绘制出非常出色好看的View
参考文章
Paint&Canvas&Path 系列
1.https://www.jianshu.com/p/2aa0b8585f68
主要讲解
Paint.setStyle();
//设置画笔的style (三种:FILL填充 FILL_AND_STROKE填充加描边 STROKE描边 )
Paint.setShader(Shader shader)
//设置图像效果
Paint.setShadowLayer(float radius ,float dx,float dy,int color);
//在图形下面设置阴影层
(其他的比较简单很容易理解)
2.https://www.jianshu.com/p/adbe33e887be
Canvas 各种绘制方法的使用 和 Canvas本身的平移/旋转/缩放,特别注意RectF和Rect的区别
3.https://www.jianshu.com/p/9ad3aaae0c63
Path各种添加图形的方法使用 和 其他的常用方法
...
2.关于重绘
普通的重绘:
View绘制分三个步骤,顺序是:onMeasure
,onLayout
,onDraw
。调用invalidate
方法只会执行onDraw
方法;调用requestLayout
方法只会执行onMeasure
方法和onLayout
方法,并不会执行onDraw
方法。
所以当我们进行View更新时,若仅View的显示内容发生改变且新显示内容不影响View的大小、位置,则只需调用invalidate
方法;若View宽高、位置发生改变且显示内容不变,只需调用requestLayout
方法;若两者均发生改变,则需调用两者,按照View的绘制流程,推荐先调用requestLayout
方法再调用invalidate
方法。
invalidate
和postInvalidate
(更常用):
invalidate方法只能用于UI线程中,在非UI线程中,可直接使用postInvalidate方法。
结合动画的重绘:
很笨的方法:可以自己使用Rxjava开一个异步线程,在线程中开启循环,每次修改某个参数,每次循环线程sleep 10ms,这样就可以有一个看似连续性的动画效果
通常方法:使用属性动画ObjectAnimator
一句话属性动画的特点:
根据属性值变化区间和持续时间,在每个时间点确定一个值,调用动画作用对象的某条属性的set方法,修改该属性的值,具体想要这个这个属性值改变之后,动画效果怎么表现,需要在作用对象的set方法中自定义。
3.简单的自定义View学习
一个精致的打勾小动画View
https://github.com/ChengangFeng/TickView
`
网友评论