全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Android自定义view Path 的高级用法之搜索按钮动画

关于Path之前写的也很多了,例如path绘制线,path绘制一阶,二阶和三阶贝塞尔路径,这些都是path的基本用法。今天我要带大家看的是Path 的高级用法,先上图,再吹。

效果大致是这样的。看着是不是挺好。话不多说,切入正题:

既然今天要谈Path的高级用法,那就先来讲一讲(Path -- 中文 )就是“路径”既然是路径,从我们面向对象的想法的话,我们就容易想到 路径 的长度,路径的某一点等。想到这里我们就引出今天 的主要 类--------PathMeasure,字面意思很容易理解--翻译成 路径测量。对这就是我们用来测量路径的类。既然是一个类,我们就要看他集体有哪些方法和属性。

1.构造方法:

一个是有参数,一个无参数。

无参数就很容易理解就是直接创建对象,那有参数呢?

PathMeasure(Path path, boolean forceClosed) ;第一个参数 Path  咿 !这不就是我们的Path 了吗。对既然是测量类,那就是要确定需要测量的那个路径,那第二个参数呢?

第二个参数是用来确保 Path 闭合,如果设置为 true, 则不论之前Path是否闭合,都会自动闭合该 Path(如果Path可以闭合的话)。

2.方法:

这方法还挺多,都是干啥的呢?就找几个重要的,常用的讲讲:

第一个那就是 setPath(Path path, boolean forceClosed)

这方法一看就知道设置path 路径的,就是如果我们创建 PathMeasure,时用的是无参的构造方法时 ,这时候就要用此方法,告诉PathMeasure 当前需要测量的是哪一个path路径。(个人喜欢用无参,比较灵活)。

第二个那就是getLength(),很容易理解就是 获得 path 的总长度。

第三个:getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo),这个方法非常重要,截取片段,截取的结果就是,我们的path路径。参数也很好理解。第一个是开始的距离,第二个是结束的距离(相对于起点==既然是起点,我们怎么找他们的起点呢,其实就是我们绘制图画笔开始的哪一点)。第三个参数就是返回的路径。第四个参数起始点是否使用 moveTo 用于保证截取的 Path 第一个点位置不变。

第四个:getPosTan(float distance, float[] pos, float[] tan),这个也是非常重要的,为什么呢?听我解释一下他的参数就知道了。第一个参数是距离(相对于绘制起点的路径距离),第二个参数是距离起点的坐标点,第三个参数返回的是正玄函数tan@角度。

对这些参数了解之后下面就来讲解我们今天的例子:

首先我们先来个简单的:例如

如图这样的分析过程:

1.首先绘制一个圆(蓝色的),从45度开始绘制,注意圆的起点。

2.同圆心绘制大圆(辅助圆)用来辅助绘制蓝色的线。

3.通过getPosTan(float distance, float[] pos, float[] tan)方法得到两个圆的终点的坐标。

4.利用lineTo(x,y)绘制线。就得到我们的搜索图形了。

5.接下来就是实时 截取片段。getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo),截取从距离0到getlength();这样就产生了一个动态的效果了。

看代码:

关于画笔,canvas画布,valueanimator动画,这些请看之前的博客,都有详细讲解。

public class MySearch extends View {
  Paint paint;
  Path searchPath; //搜索的圆
  Path ciclePath; //外圆
  //获得宽高
  int w;
  int h;
  //这是保存截取时,返回的坐标点
  float serpos[];
  float cicpos[];
  //测量 path 的类
  PathMeasure measure;
  //动画产生的实时数据
  float value;
  public MySearch(Context context) {
    this(context,null);
  }
  public MySearch(Context context, @Nullable AttributeSet attrs) {
    this(context,attrs,0);
  }
  public MySearch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    //获得屏幕的宽高
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    w = wm.getDefaultDisplay().getWidth();
    h = wm.getDefaultDisplay().getHeight();
    //初始化数据
    serpos = new float[2];
    cicpos = new float[2];
    //画笔
    paint = new Paint();
    paint.setStyle(Paint.Style.STROKE);
    paint.setDither(true);
    paint.setStrokeWidth(6);
    paint.setAntiAlias(true);
    //初始化路径
    initPath();
    //初始化动画
    initAnimator();
  }
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //移动画布的远点到屏幕中心
    canvas.translate(w/2,h/5);
    paint.setColor(Color.BLUE);
    //这是截取方法返回的路径
    Path dra = new Path();
    //解除硬件加速,不然没效果
    dra.reset();
    dra.lineTo(0,0);
    //设置当前需要测量的path
    measure.setPath(searchPath,false);
    //开始截取
    boolean s = measure.getSegment(measure.getLength()*value,measure.getLength(),dra,true);
    //绘制路径
    canvas.drawPath(dra,paint);
  }
  /**
   * 初始化路径
   */
  public void initPath(){
    paint.setColor(Color.BLUE);
    //搜索的圆
    searchPath = new Path();
    RectF rectF = new RectF(-50,-50,50,50);
    searchPath.addArc(rectF,45,359.9f);
    //辅助圆
    ciclePath = new Path();
    RectF rectF1 = new RectF(-100,-100,100,100);
    ciclePath.addArc(rectF1,45,359.9f);
    //测量类
    measure = new PathMeasure();
    measure.setPath(searchPath,false);
    //获取坐标
    measure.getPosTan(0,serpos,null);
    measure.setPath(ciclePath,false);
    //获取坐标
    measure.getPosTan(0,cicpos,null);
    //根据两点坐标绘制线
    searchPath.lineTo(cicpos[0],cicpos[1]);
  }
  /**
   * 初始化动画
   */
  public void initAnimator(){
    ValueAnimator animator = ValueAnimator.ofFloat(0,1);
    animator.setDuration(2600);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        value = (float) animation.getAnimatedValue();
        postInvalidate();
      }
    });
    animator.start();
  }
}

第一个图大家学会了,去练习一下吧!


# android  # 自定义view  # path搜索按钮动画  # Android自定义View 使用PathMeasure简单模仿系统ProgressBar(四)  # Android自定义View实现支付宝支付成功-极速get花式Path炫酷动画  # Android自定义View系列之Path绘制仿支付宝支付成功动画  # Android通过Path实现搜索按钮和时钟复杂效果  # 第一个  # 的是  # 第二个  # 很容易  # 第三个  # 这是  # 那就是  # 非常重要  # 相对于  # 都是  # 是一个  # 他们的  # 看着  # 几个  # 都有  # 很好  # 是有  # 那就  # 是这样  # 这就是 


相关文章: ,sp开头的版面叫什么?  建站之星CMS五站合一模板配置与SEO优化指南  网站制作与设计教程,如何制作一个企业网站,建设网站的基本步骤有哪些?  Swift中switch语句区间和元组模式匹配  如何通过服务器快速搭建网站?完整步骤解析  宝塔建站教程:一键部署配置流程与SEO优化实战指南  如何用搬瓦工VPS快速搭建个人网站?  免费网站制作appp,免费制作app哪个平台好?  外贸公司网站制作哪家好,maersk船公司官网?  高端建站三要素:定制模板、企业官网与响应式设计优化  盐城做公司网站,江苏电子版退休证办理流程?  建站之星导航如何优化提升用户体验?  Android自定义listview布局实现上拉加载下拉刷新功能  如何在西部数码注册域名并快速搭建网站?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  实现点击下箭头变上箭头来回切换的两种方法【推荐】  深圳网站制作的公司有哪些,dido官方网站?  佛山网站制作系统,佛山企业变更地址网上办理步骤?  建站之星多图banner生成与模板自定义指南  如何优化Golang Web性能_Golang HTTP服务器性能提升方法  建站与域名管理如何高效结合?  如何通过云梦建站系统实现SEO快速优化?  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  建站之星下载版如何获取与安装?  建站之星安装后界面空白如何解决?  宝塔建站无法访问?如何排查配置与端口问题?  python的本地网站制作,如何创建本地站点?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  如何登录建站主机?访问步骤全解析  网站制作新手教程,新手建设一个网站需要注意些什么?  网站代码制作软件有哪些,如何生成自己网站的代码?  北京网站制作公司哪家好一点,北京租房网站有哪些?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  如何选择适合PHP云建站的开源框架?  婚礼视频制作网站,学习*后期制作的网站有哪些?  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  微信小程序 五星评分(包括半颗星评分)实例代码  如何通过免费商城建站系统源码自定义网站主题与功能?  零服务器AI建站解决方案:快速部署与云端平台低成本实践  如何通过虚拟机搭建网站?详细步骤解析  如何获取开源自助建站系统免费下载链接?  如何快速打造个性化非模板自助建站?  购物网站制作公司有哪些,哪个购物网站比较好?  详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)  深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。