假期某天突然想做一个转盘,以满足某一天不知道吃什么的时候由转盘决定午餐内容(=。=)作为一个初学者——没有所谓的客户需求只有自己是否满意:)
首先即需要做一个转盘出来,搜索到了canvas,一个常用的2D绘图软件,html5里面也经常用到这个,android做了移植,系统自带,直接import android.graphics.canvas即可。
canvas简单科普
canvas在绘图的过程中需要四个基本组件,分别是bitmap(存储像素),canvas(画布),所画内容(圆,长方形blabla),还有画笔paint(线条粗细,实心还是空心,抗锯齿啊blabla)。bitmap是最终呈现结果的一个平台,下图是canvas的创建过程
可以发现canvas必须传入一个bitmap参数,Canvas 本意是画布的意思,但是在Android中,它就只是一个媒介,可以通过Canvas来调用drawRect,drawCircle等等,但是实际上画的这些东西最终展现的时候, 都是像素,但是只有Bitmap才能保存像素,而Canvas并不行,所以在创建Canvas的时候,就必须传递一个Bitmap,用来承载画的内容。
形象的说:bitmap是一张纸,canvas是画布,笔只能通过画布画到纸上,最终拿走画布展示给大家的还是那张纸上的内容。
canvas绘图基本函数
我只讲一下我接下来要使用的函数
canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
第一个参数RectF传入一个区域,画的圆弧将会在这个区域内,具体不懂自行百度thx。第二个参数startangle顾名思义开始角度,第三个扫过的弧度,第四个参数true封闭的,false则是一段弧线,第五个参数传入画笔。
canvas.rotate(angle)
使画布旋转一定的角度
canvas.translate(x,y)画布中心移动到(x,y)
转盘的实现
android中图像需要显示在view中,于是我们首先建立一个类继承自view
view中有一个ondraw函数, 可以实现绘图功能,我们所有的绘制都应该在这个函数中实现。所以我们需要重写这个函数
接着设定画笔Paint的参数
setStyle中的FILL代表填满,STROKE代表空心的
想象一下绘制如图所示的圆盘,其实是由12块扇形组成的,而drawarc刚好可以绘制扇形,每绘制一个扇形,将画布旋转30度接着画,旋转一圈图片就实现了。至于颜色是在Paint画笔中设定的,传入一个自己想要的颜色数组即可。
由于我想将这个圆绘制在view正中间,mWidth,mHeight为view的长宽,(r的设定是自己设置的1.1倍的最小长or宽-50【大家也可以自行设定】)
rect表示创建了一个矩形区域,接着就可以用一个for循环
于是上图的扇形就画好了!
可是转盘上需要添加字体或者图片吧,起码得有菜名啊!!!QAQ
这时候就要用到canvas的另外几个绘制文字的函数,比如 我用的drawText(text,x,y,paint)第一个是文本,x,y代表传入坐标(其实不太准确,自行百度吧各位~)最后一个当然是传入画笔啦,由于有12个扇形,最简单的方法就是在for循环里同时加上drawText,每画一个扇形加一次文字xixi。【point:画布是可以覆盖的!如果你先绘制文字再绘制扇形,文字就被遮挡看不见了!】
这里传入了每一个菜名的数组~这时候需要确定x,y的坐标了!
想象了一下最终结果应该是这样,每个都大概是扇形中间的样子,哦哈想到了三角函数!对!
验证一下~哈哈实现了!然后把这个view添加到mainActivity的XML中并设置了一个id/PaintBoard
如何让它旋转起来呢
这部分就大致属于简单动画部分了!好在android有一个函数实现了这个功能
在MainActivity里开始添加动画了!
想要实现的效果是,点击转盘转盘就开始转动
RotateAnimation参数:
如果pivotXType=Animation.RELATIVE_TO_SELF,则参数pivotXValue为旋转中心在控件自身水平位置百分比,如果X和Y的Value都设置为0.5,则该控件以自身中心旋转。
看完上面的那个链接相信掌握的也八九不离十了,但是问题又来了,一般转盘一开始都是匀速的,然后慢慢变慢这个怎么办呢?rotate提供了LinearInterpolator和DecelerateInterpolator还有Accelerateinterpolator,于是我创建了两个Rotate——rotate1和rotate2,一个匀速运动一个减速运动,匀速的运动时长固定为1000,减速的那个rotate2使用了随机数Number在200-2000范围内波动。
对rotate1进行监听!!!setanimationlistener中重写了三个方法,分别对应的是停止开始和重复时应该有的操作!我们只需要在rotate1结束的时候让我们的view开始参数为rotate2的转动就行了!mPaintBoard.startAnimation(rotate2);
好了现在转盘可以转了!但是没有指示标~偷懒的我在下载了个箭头icon然后添加到xml
大概是这样...
这时候基本的转盘已经实现了!
Question1:字体的问题。。。当转盘转起来的时候,
这些字都歪了!
嗯对应该做一个这样子的才对吖!
于是蠢蠢的自己分别计算了四个坐标位置,
然后把菜名拆开填进去...
最终的最终!