android 使用Path实现搜索动态加载动画效果

本文介绍了如何使用Path和动画在Android中实现搜索动态加载的动画效果。通过分析和绘制两个同心圆,从45度开始绘制,并利用值动画改变起点位置,最终形成动态的搜索图标动画。详细步骤包括静态图的绘制、动态效果的实现以及大圆的旋转动画。文章还提到了可能的优化和注意事项,并提供了GitHub源码链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天实现一个搜索动态加载数据的动画效果,还是先看效果吧,用文字描述干巴巴的,看图说话什么都明白了,


实现这个就是使用Path中的getSegment()不断的去改变它截取片段的start和stop,再结合动画,今天就分步骤实现它,看完以后你也会觉的不是很难,只是没想到这么实现而已,所以要多见识,所谓眼界决定你的高度,还是延续我写博客的习惯,一步步分析,第一步就是绘制如下图:


如果单纯的绘制这个图很简单很简单的,绘制一个圆,然后再绘制一根线就搞定,但是要考虑这里的效果,就不能这么干了,如果你看了上面的gif图就知道,其实这是2个同心圆,然后前一个path的起点和后一个path的起点相连接就是形成一条直线了,但是path中的图形内容也就是这个圆是怎么绘制出来的呢?如果是绘制圆的话,上面的线起点和终点位置怎么去计算,这是个问题,但是我们绘制圆还可以使用绘制椭圆的形式也是可以绘制达到圆的效果,从45度开始绘制一个圆,是不是这个线的起点搞定了,分析图如下:


那么好,根据上面的分析开始写代码绘制出一个静态的搜索图:

package com.tuya;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/12/17.
 */
public class DynamicSearchView2 extends View {
    private Paint paint;
    private int width;//view的宽度
    private int height;//view的高度
    private Path searchPath;
    private Path circlePath;
    private float BigCircleRectWidth;//搜索圆对应的外切正方形边长
    private PathMeasure pathMeasure;
    private float[] pos;
    public DynamicSearchView2(Context context) {
        this(context,null);
    }
    public DynamicSearchView2(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public DynamicSearchView2(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(3);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        initPath();
    }
    /**
     * 初始化path
     */
    private void initPath() {
        searchPath = new Path();
        circlePath = new Path();
        if(width>height){
 //长方形
            BigCircleRectWidth = height;
        }else if(width<height){
            BigCircleRectWidth = width;
        }else{
            BigCircleRectWidth = width;
        }
        float smallbordWidth =BigCircleRectWidth/8;
        RectF searchRect = new RectF(-smallbordWidth,-smallbordWidth,smallbordWidth,smallbordWidth);

        searchPath.addArc(searchRect,45,360);
        float bigBordWidth = smallbordWidth*2;
        RectF circleRect = new RectF(-bigBordWidth,-bigBordWidth,bigBordWidth,bigBordWidth);
        circlePath.addArc(circleRect,45,-360);
        pathMeasure = new PathMeasure(circlePath,false);
        pos = new float[2];
        pathMeasure.getPosTan(0,pos,null);
        searchPath.lineTo(pos[0],pos[1]);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(width/2,height/2);//平移画布把这个view的中心点当做原点
        canvas.drawPath(searchPath,paint);
        canvas.drawPath(circlePath,paint);
    }
}

效果图:


本来这个外圆是不需要draw上去的,我在这绘制上去只是告诉你这二个圆是有一定的联系,哪为什么这根线是这样的呢?我们在绘制这个圆的时候是从45度开始绘制360刚好是一周,形成了一个圆,现在做个测试不要360,就写个330度,效果如下:


这个时候你会发现这条线是对的,导致问题其实是这样的,如图分析:


把绘制椭圆的关键代码:

searchPath.addArc(searchRect,45,358);

circlePath.addArc(circleRect,45,-358);

不要写成360,改为358试试,效果图:


发现这线是不是正常了,至于外面的圆还有点缺口,第一你可以把358改成359应该没事了,还有就是我们其实真实的效果并不需要这个外面的圆,所以不改也没事,那么好,第一步算是完成了,现在想想第二步怎么实现,先把第二步的效果用gif展示看下,不然光想没思路,就像你看美女,第一眼看那,是吧,就不多说了!要有画面感,


还是画布分析:


哪我们只要改变startD这个离起始点的位置值就ok,当然有很多种方法,但是android中基本上都是使用值动画,ok,根据这个思路实现这个第二步逻辑:

package com.tuya;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/12/17.
 */
public class DynamicSearchView2 extends View {
    private Paint paint;
    private int width;//view的宽度
    private int height;//view的高度
    private Path searchPath;
    private Path circlePath;
    private float BigCircleRectWid
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值