Canvas实现炫酷动画SearchView
Posted 花花young
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Canvas实现炫酷动画SearchView相关的知识,希望对你有一定的参考价值。
前言
在Android官方对Canvas描述是:Canvas类容纳所有和Draw(绘制)相关的方法。为了去Draw,你需要具备四个要素,1是Bitmap用来承载像素信息、2是Canvas用来管理Draw相关方法、3是绘制基元(例如,Rect,Path,text,Bitmap)、4是一个画笔(用来描述图像的颜色和风格)
本文之前有关于Paint的文章
绘图不可或缺的画笔Paint-使用篇
绘图不可或缺的画笔Paint-渲染篇
绘图不可或缺的画笔Paint-滤镜篇
Part 1、Canvas实现炫酷的搜索
效果~
实现此功能很简单,只要动态改变圆弧区域和把手区域即可,这里我们让把手与竖直方向成45度角,如下图所示
1、绘制正常的图形
看代码
private void drawNormalView(Paint paint, Canvas canvas)
centerX = getWidth() / 2;
centerY = getHeight() / 2;
circleL = Math.PI * 2 * RADios;
mRectF.left = centerX - RADIOS;
mRectF.right = centerX + RADIOS;
mRectF.top = centerY - RADIOS;
mRectF.bottom = centerY + RADIOS;
//设置画笔的样式
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(mRectF, 0, 360, false, paint);
float startX = (float) (Math.sin(angle) * RADIOS + centerX);
float startY = (float) (Math.cos(angle) * RADIOS + centerY);
float endX = (float) (Math.sin(angle) * (RADIOS + LINE) + centerX);
float endY = (float) (Math.cos(angle) * (RADIOS + LINE) + centerY);
canvas.drawLine(startX, startY, endX, endY, paint);
上面是直观的绘制方式,当然我们也可以使用Canvas的旋转来实现,我们只需要在绘制把手之前的时候将画布旋转45度,然后在save和restore将画布保存并恢复为原始的状态。
private void drawNormalView(Paint paint, Canvas canvas)
cr = getWidth() / 20;
cx = getWidth() / 2;
cy = getHeight() / 2;
radiusL = (float) (Math.PI * cr * 2);
//绘制的圆形范围
mRectF.left = cx - cr;
mRectF.right = cx + cr;
mRectF.top = cy - cr;
mRectF.bottom = cy + cr;
canvas.save();
//设置画笔
paint.reset();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
canvas.rotate(45, cx, cy);
canvas.drawLine(cx + cr, cy, cx + cr * 2, cy, paint);//绘制把手
canvas.drawArc(mRectF,0,360,false,paint);
canvas.restore();
tips:
canvas:drawArc() : startAngle:其实角度,相对于X轴正方向 sweepAngle : 画多少角度的弧度(正值顺时针旋转) userCenter : false只有一个纯弧线 true闭合的边
效果~
2、绘制动态时候的效果
这里我们使用一个属性动画来不断更新绘制的进度
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(800l);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new AnimatorUpdateListener()
@Override
public void onAnimationUpdate(ValueAnimator animation)
mpro = (float) animation.getAnimatedValue();
mySearchView.invalidate();
);
就这样mpro的范围为0~1,根据这个范围来进行绘制即可,这里可以分为2部分:一部分为0~0.5 一部分为0.5~1
(1)0~0.5阶段
if (mpro < 0.5) //绘制圆和把手
canvas.drawArc(mRectF, 45, 360 * (mpro * 2 - 1), false, paint);
float startX = (float) (Math.sin(angle) * RADIOS + centerX);
float startY = (float) (Math.cos(angle) * RADIOS + centerY);
float endX = (float) (Math.sin(angle) * (RADIOS + LINE) + centerX);
float endY = (float) (Math.cos(angle) * (RADIOS + LINE) + centerY);
canvas.drawLine(startX, startY, endX, endY, paint);
L = circleL * (360 * mpro * 2) / 360f;
这里记录了一下去掉圆弧的长度,用来对搜索图形平移
(2)0.5~1.0阶段
float startX = (float) (Math.sin(angle) * (RADIOS + LINE * (mpro * 2 - 1)) + centerX);
float startY = (float) (Math.cos(angle) * (RADIOS + LINE * (mpro * 2 - 1)) + centerY);
float endX = (float) (Math.sin(angle) * (RADIOS + LINE) + centerX);
float endY = (float) (Math.cos(angle) * (RADIOS + LINE) + centerY);
canvas.drawLine(startX, startY, endX, endY, paint);
L = L + LINE * (mpro * 2 - 1);
Ok,最后不要忘记绘制底部的线
float endX = (float) (Math.sin(angle) * (RADIOS + LINE) + centerX);
float endY = (float) (Math.cos(angle) * (RADIOS + LINE) + centerY);
float startX = (float) (endX - L);
float startY = endY;
canvas.drawLine(startX, startY, endX, endY, paint);
就这样炫酷的搜索搞定了。当然你可以为搜索图形增加平移的效果
mRectF.left = (float) (getWidth() / 2f - RADIOS + (getWidth() / 3f) * mpro);
mRectF.right = mRectF.left + 2 * RADIOS;
mRectF.top = getHeight() / 2f - RADIOS;
mRectF.bottom = getHeight() / 2f + RADIOS;
centerX = mRectF.left + RADIOS;
centerY = mRectF.top + RADIOS;
效果~
以上是关于Canvas实现炫酷动画SearchView的主要内容,如果未能解决你的问题,请参考以下文章