扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
LinearGradient 和 SweepGradient,这次讲解RadialGradient;
创新互联公司专业为企业提供涿州网站建设、涿州做网站、涿州网站设计、涿州网站制作等企业网站建设、网页设计与制作、涿州企业网站模板建站服务,十多年涿州做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
RadialGradient被称为放射渐变,就是从中心向外圆形渐变。
两个构造函数,第一个构造函数可以实现两种颜色的渐变,第二个构造函数可以实现多个颜色的渐变。
参数说明:
centerX ,centerY:shader的中心坐标,开始渐变的坐标。
radius:渐变的半径,
centerColor,edgeColor:中心点渐变颜色,边界的渐变颜色,
colors:渐变颜色数组,
stoops:渐变位置数组,类似扫描渐变的positions数组,取值[0,1],中心点为0,半径到达位置为1.0f,
tileMode:shader未覆盖以外的填充模式。
构造函数:
RadialGradient(float centerX, float centerY, float radius, @ColorInt int centerColor, @ColorInt int edgeColor, @NonNull TileMode tileMode);
提供中心坐标,半径,颜色值,TileMode
Stops数组取值为[0-1],一般为从小到大,表示每个位置对应的颜色值,如果stops不为null,colors必须和stops一一对应,否则可能导致崩溃,如果stops为null,各颜色从中心到边界线性渐变。
stops数组为null,四种颜色线性渐变:
stops数组不为null:
如果数组多余颜色个数:
大致做个小例子,如果需要线上使用需要考虑很多问题,类似ondraw最好不要声明对象等:
替换为多颜色 private int[] colors = {Color.YELLOW, Color.RED, Color.BLUE, Color.GREEN};
android绘图之Paint(1)
android绘图之Canvas基础(2)
Android绘图之Path(3)
Android绘图之drawText绘制文本相关(4)
Android绘图之Canvas概念理解(5)
Android绘图之Canvas变换(6)
Android绘图之Canvas状态保存和恢复(7)
Android绘图之PathEffect (8)
Android绘图之LinearGradient线性渐变(9)
Android绘图之SweepGradient(10)
Android绘图之RadialGradient 放射渐变(11)
Android绘制之BitmapShader(12)
Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13)
Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14)
Android绘图之贝塞尔曲线简介(15)
Android绘图之PathMeasure(16)
Android 动态修改渐变 GradientDrawable
画红圈
?xml version="1.0" encoding="utf-8"?
xmlns:android=""
android:shape="oval"
android:useLevel="false"
solid android:color="@color/red" /
android:width="1dp"
android:color="@color/white" /
android:width="20dp"
android:height="20dp" /
/shape
画黄圈
?xml version="1.0" encoding="utf-8"?
shape xmlns:android=""
android:shape="oval"
android:useLevel="false"
solid android:color="@color/yellow" /
android:width="1dp"
android:color="@color/white" /
android:width="20dp"
android:height="20dp" /
/shape
画绿圈
?xml version="1.0" encoding="utf-8"?
shape xmlns:android=""
android:shape="oval"
android:useLevel="false"
solid android:color="@color/green" /
android:width="1dp"
android:color="@color/white" /
android:width="20dp"
android:height="20dp" /
/shape
Github链接
画2D图形有两种方法:
Canvas实际上是封装了各种draw方法的类,调用draw方法把图形绘制到底层的Surface上,即绘制在Window上。
这个例子中构造了两个Canvas和一个Bitmap,分别调用其draw方法,先是mCanvas往Bitmap里绘制一个方块,再在onDraw方法内调用canvas.drawBitmap绘制这个方块。
思考一个问题,为什么mCanvas需要设置Bitmap?
很简单,因为它没有持有一块内存地址,自然没法绘制。来看一下draw的起点ViewRootImpl(软件绘制,不开启硬件加速下)。
这个通过mSurface.lockCanvas返回的Canvas是View.draw的canvas变量,所以当1,2情况时,Canvas都持有一个Bitmap,指向共享内存里的某一小块,当调用Canvas.draw方法时就能绘制出东西。但对于自定义Canvas来说并不是,即使设置一个Bitmap和绘制了Bitmap,但不往共享内存上写,屏幕上是不会显示的,SurfaceView同理,通过Surface.lockCanvas获取持有共享内存的Canvas,绘制完毕后调用Surface.unlockCanvasAndPost把绘制内容显示到surface上并release掉Canvas。
顺带一提Canvas.save和Canvas.restore方法,如下Demo
效果图如
画的是三个颜色和旋转角度都不同的小方形。
步骤1把默认坐标系旋转20°,画出第一个蓝色的方形,步骤2保存当前的matrix(旋转了20°),继续旋转20°,此时坐标系已经旋转了40°,画出第二个黄色的方块,步骤3,恢复上一步保存的matrix(旋转了20°),此时坐标系还是旋转了20°,步骤4,再旋转40°,此时坐标系旋转了60°,画出第三个黑色方块。
Canvas.save用于保存当前matrix和clip,Canvas.restore用于恢复上次保存的matrix和clip。
Drawable是一个能画出来的物体的抽象,使用前需要调用setBounds确定位置和大小,通过getIntrinsicHeight和getIntrinsicWidth取到实际大小。Drawable可以有几种形式存在:Bitmap、Nine Patch、Vector、Shape、Layers等。
从Resource.getDrawable会判断是否.xml结尾,不是的话走6,7步,如果从xml中读取,需要getResource.getDrawable - ResourceImpl.loadDrawableForCookie - drawable.createFromXml - DrawableInflater.inflateFromXmlForDensity - drawable.inflateFromTag
看一下Shape实现类GradientDrawable的inflate实现,读取各项属性并赋值,到draw方法。
调用canvas.drawRect把mRect画出来,而mRect的赋值在ensureValidRect。[图片上传失败...(image-a25af0-1515826613001)]
bounds在哪里设置的?答案是ImageView.updateDrawable内,会调用Drawable.getIntrinsicHeight赋值(从xml中size属性读取),再调用configureBounds - setBounds,如果使用的不是ImageView,一定要在draw之前 调用setBounds ,否则size就会出错。
回到loadDrawableForCookie,再看一下6,7步加载图片的过程,通过AssetManager读取图片流数据,通过Drawable.createFromResourceStream这个我们经常使用的方法获取到Drawable。
取到屏幕密度之后调用BitmapFactory.decodeResourcesStream,计算密度后调用native创建Bitmap,感兴趣的同学可以看下更具体的分析文章(如 理解Bitmap )。
本文探究了两点
Android 7.1.1 源码
Android 官方文档, Canvas and Drawable , Drawable 等
前面讲解了Canvas的基本概念, Android绘图之Canvas概念理解(5) ,
对Canvas的概念进行了分析,但是没有说明和屏幕的关系,Canvas不等于屏幕,屏幕不会动的,我们也无法对屏幕进行(平移,缩放等)操作,只能对Canvas进行操作,所以对Canvas进行操作,屏幕不动,最终会导致看到的图像不同。
下面开始讲解Canvas的变幻操作:
包括:translate,rotate,scale,skew,clip,clipout,matrix
先从最简单的平移开始:
对Canvas进行平移,
dx: x轴方向进行平移,正值向屏幕右侧
dy:y轴方向进行平移,正值向屏幕下方
绘制两个点查看原点位置。
原点显然改变了,以后再绘制任何形状都是以translate后的原点开始绘制。
参数说明
sx:横向的缩放,默认为1,小数缩小,整数放大
sy:纵向的缩放,默认为1,小数缩小,整数放大
px,py,看源码知道是先translate,执行sx,sy然后再translate反方向。
第二次translate的坐标为(-px sx,-px sy),最终的效果就是px,py是缩放后不动的点。
缩放后坐标减半。
如果想控制缩放后的位置,如何控制呢,这就需要第二个函数。
还可以控制其他位置,例如控制缩放后在中心。
rotate有两个函数:
rotate(float degrees)
rotate(float degrees, float px, float py)
Degree:旋转的角度,正值为顺时针,负值为逆时针
Px,py:旋转的中心,如果不指定旋转中心默认为(0,0)点
指定旋转中心为矩形中心
参数说明:
sx:画布在x方向上倾斜相应的角度,sx倾斜角度的tan值,
sy:画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值,
根据矩形或者路径裁剪画布,画布被切割之后,只有部分区域可用,其他区域无法绘制内容。
Clip函数切割的区域可用,clipOut未被切割的区域可用。(过时函数不再讲解)
Matrix提供了一些方法来控制变换:
android绘图之Paint(1)
android绘图之Canvas基础(2)
Android绘图之Path(3)
Android绘图之drawText绘制文本相关(4)
Android绘图之Canvas概念理解(5)
Android绘图之Canvas变换(6)
Android绘图之Canvas状态保存和恢复(7)
Android绘图之PathEffect (8)
Android绘图之LinearGradient线性渐变(9)
Android绘图之SweepGradient(10)
Android绘图之RadialGradient 放射渐变(11)
Android绘制之BitmapShader(12)
Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13)
Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14)
Android绘图之贝塞尔曲线简介(15)
Android绘图之PathMeasure(16)
Android 动态修改渐变 GradientDrawable
Paint 讲解开篇
android中绘制特定图案类似显示中的绘画需要画笔和画纸,为此android提供了Paint和Canvas。
Paint和Canvas分别代表画笔和画布。
The Paint class holds the style and color information about how to draw geometries, text and bitmaps.
Paint类似画笔,保存着绘制文本,图形,图片的样式和颜色信息。(颜色,宽度,粗细,透明度,字体样式,字体大小)。
提供了三种初始化方法:
Paint(),
Paint(int flags),
Paint(Paint paint)。
第二种构造函数传入了flag,相当于无参构造之后调用了setFlags(int),有很多种flag,这里举个例子UNDERLINE_TEXT_FLAG(其他的flag见developers文档),绘制文字时会有下划线,多个flag或可以达到设置多个flag的目的。
Paint常用的设置函数:
setAlpha()透明度
setAntiAlias()抗锯齿
setColor(),setARGB()设置颜色
setStyle(Paint.Style style) 设置填充样式
setStrokeCap(Paint.Cap cap) 画笔的样式(落笔,收笔时)
setStrokeJoin(Paint.Join join)连接点的样式
setStrokeWidth(float width)设置画笔宽度
setShadowLayer(float radius, float dx, float dy, int shadowColor) 设置阴影
setTextSize(float textSize) 字体大小
setTextAlign(Paint.Align.RIGHT)设置字体对齐方式
后期讲解:
setColorFilter(ColorFilter filter) 设置颜色过滤
setUnderlineText(true) 下划线
setPathEffect() 设置路径效果
setTypeface() 设置字体风格
setFilterBitmap() 设置图片过滤
setXfermode(Xfermode xfermode) xfermode设置图像混合模式
setShader(Shader shader) 设置shader包括渐变shader,图片shader
。。。。。。。。
setAlpha(int a) 设置透明度,a 值得范围 [0..255],仅仅改变setColor()的颜色的透明度,不改变颜色值,0是完全透明,255完全不透明。
注意:需要先调用setColor(),再调用setAlpha才会生效,否则将会被覆盖,因为setColor中包含了alpha。
setStyle设置填充样式,所谓填充的样式指只绘制线或者绘制同时填充:
Paint.Style.FILL 填充内部,会把闭合区域填充颜色
Paint.Style.FILL_AND_STROKE 填充内部和描边
Paint.Style.STROKE 仅描边,仅仅绘制边界
默认FILL 填充内部,
STROKE样式
FILL_AND_STROKE样式和FILL 类似但当画笔宽度很宽时会产生不同
setColor,setARGB设置颜色,设置画笔的颜色,setARGB()参数范围0-255。
setAntiAlias(boolean) 抗锯齿,使边界更顺滑(有些屏幕分辨率不高,导致像素点比较大,绘制边界可能会有颗粒感,打开抗锯齿边界颗粒感会减少)。
setTextSize(float textSize) 字体大小,单位是px,如果是dp要注意转换。
setTextAlign(Paint.Align.RIGHT)设置字体对齐方式,根据下面的实例可以,对齐方式基于开始绘制的点。
一起讲解:
mPaint.setTextSize(50);
mPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("android Paint 学习 LEFT",300,300,mPaint);
mPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("android Paint 学习 CENTER",300,400,mPaint);
mPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText("android Paint 学习 RIGHT",300,500,mPaint);
setTextAlign对齐是相对于开始绘制的坐标点。
setShadowLayer(float radius, float dx, float dy, int shadowColor) 设置阴影
mPaint.setShadowLayer(10,-20,30,Color.GRAY);
canvas.drawText("android Paint 学习 CENTER",getWidth()/2,450,mPaint);
setShadowLayer(float radius, float dx, float dy, int shadowColor)
Radius设置角度,dx,dy控制字体的上下左右出现,有正负之分,dx的正负代表右左,dy的正负代表下上。
setStrokeCap(Paint.Cap.ROUND)
设置绘制起始点和结尾点的样式,
三种样式ROUND,BUTT,SQUARE
Cap.ROUND(圆形)、Cap.SQUARE(方形)、Paint.Cap.BUTT(无)
ROUND:
BUTT和SQUARE差别不大:
setStrokeJoin(Paint.Join join),设置绘制path连接点的样式
mPaint.setStrokeJoin(Paint.Join.ROUND);
// mPaint.setStrokeJoin(Paint.Join.MITER);
// mPaint.setStrokeJoin(Paint.Join.BEVEL);
Join.MITER(结合处为锐角)、
Join.Round(结合处为圆弧)、
Join.BEVEL(结合处为直线)
ROUND样式:
MITER样式:
BEVEL样式:
setXfermode(Xfermode xfermode) xfermode设置图像混合模式
setShader(Shader shader) 设置shader包括渐变shader,图片shader
还有很多其他属性会后续讲解。
android绘图之Paint(1)
android绘图之Canvas基础(2)
Android绘图之Path(3)
Android绘图之drawText绘制文本相关(4)
Android绘图之Canvas概念理解(5)
Android绘图之Canvas变换(6)
Android绘图之Canvas状态保存和恢复(7)
Android绘图之PathEffect (8)
Android绘图之LinearGradient线性渐变(9)
Android绘图之SweepGradient(10)
Android绘图之RadialGradient 放射渐变(11)
Android绘制之BitmapShader(12)
Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13)
Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14)
Android绘图之贝塞尔曲线简介(15)
Android绘图之PathMeasure(16)
Android 动态修改渐变 GradientDrawable
Canvas画布,用于绘制出各种形状配合画布的变幻操作可以绘制出很多复杂图形,基本的绘制图形分类。
提供的绘制函数:
上面四个函数都可以绘制canvas的背景,注意到PorterDuff.Mode变量,它只对两个canvas绘制bitmap起作用,所以此处暂时不讨论mode参数(没有设置mode默认使用srcover porterduff mode)。
Rect 和RectF都是提供一个矩形局域。
(1)精度不一样,Rect是使用int类型作为数值,RectF是使用float类型作为数值。
(2)两个类型提供的方法也不是完全一致。
**
rect:RectF对象,一个矩形区域。
rx:x方向上的圆角半径。
ry:y方向上的圆角半径。
paint:绘制时所使用的画笔。**
**
cx 圆心x
cy 圆心y
radius半径**
需要一个Path,代表路径后面会讲解。
绘制线的集合,参数中pts是点的集合,两个值代表一个点,四个值代表一条线,互相之间不连接。
offset跳过的点,count跳过之后要绘制的点的总数,可以用于集合中部分点的绘制。
跳过部分节点:
没有跳过点
RectF oval:生成弧的矩形,中心为弧的圆心
float startAngle:弧开始的角度,以X轴正方向为0度,顺时针
float sweepAngle:弧持续的角度
boolean useCenter:是否有弧的两边,True,还两边,False,只有一条弧
在矩形框内画一个椭圆,如果是个正方形会画出一个圆。
canvas.drawPoint();
canvas.drawPoints();
**
只需要提供两个点一个坐标就可以绘制点。
canvas.drawPoint(20,20,mPaint);
float[] points = {30,40,40,50,60,60};
canvas.drawPoints(points,mPaint);**
这几种方法类似:
canvas.drawText("好好学习,天天向上",100,100,mPaint);
drawTextOnPath
沿着一条 Path 来绘制文字
text 为所需要绘制的文字
path 为文字的路径
hOffset 文字相对于路径的水平偏移量,用于调整文字的位置
vOffset 文字相对于路径竖直偏移量,用于调整文字的位置
值得注意的是,在绘制 Path 的时候,应该在拐弯处使用圆角,这样文字显示时更舒服
大致讲解,后面会重点讲解。
Rect src
Rect dst
其中src和dst这两个矩形区域是用来做什么的?
Rect src:指定绘制图片的区域
Rect dst或RectF dst:指定图片在屏幕上的绘制(显示)区域
首先指定图片区域,然后指定绘制图片的区域。
android绘图之Paint(1)
android绘图之Canvas基础(2)
Android绘图之Path(3)
Android绘图之drawText绘制文本相关(4)
Android绘图之Canvas概念理解(5)
Android绘图之Canvas变换(6)
Android绘图之Canvas状态保存和恢复(7)
Android绘图之PathEffect (8)
Android绘图之LinearGradient线性渐变(9)
Android绘图之SweepGradient(10)
Android绘图之RadialGradient 放射渐变(11)
Android绘制之BitmapShader(12)
Android绘图之ComposeShader,PorterDuff.mode及Xfermode(13)
Android绘图之drawText,getTextBounds,measureText,FontMetrics,基线(14)
Android绘图之贝塞尔曲线简介(15)
Android绘图之PathMeasure(16)
Android 动态修改渐变 GradientDrawable
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流