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的主要内容,如果未能解决你的问题,请参考以下文章

炫酷HTML5网页背景动画

canvas 之星空动画

教你做炫酷的碎片式图片切换 (canvas)

NEXT讲坛第五回丨玩转Canvas 动画!

七款炫酷的页面特效

HTML5 金色漩涡动画