这里有新鲜出炉的精品教程,程序狗速度看过来!
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
这篇文章主要介绍了 Android 自定义 view Path 的高级用法之搜索按钮动画, 需要的朋友可以参考下
关于 Path 之前写的也很多了,例如 path 绘制线,path 绘制一阶,二阶和三阶贝塞尔路径,这些都是 path 的基本用法。今天我要带大家看的是 Path 的高级用法,先上图,再吹。
效果大致是这样的。看着是不是挺好。话不多说,切入正题:
既然今天要谈 Path 的高级用法,那就先来讲一讲(Path -- 中文 )就是 "路径" 既然是路径,从我们面向对象的想法的话,我们就容易想到 路径 的长度,路径的某一点等。想到这里我们就引出今天 的主要 类 --------PathMeasure,字面意思很容易理解 -- 翻译成 路径测量。对这就是我们用来测量路径的类。既然是一个类,我们就要看他集体有哪些方法和属性。
1. 构造方法:
一个是有参数,一个无参数。
无参数就很容易理解就是直接创建对象,那有参数呢?
第一个参数 Path 咿 !这不就是我们的 Path 了吗。对既然是测量类,那就是要确定需要测量的那个路径,那第二个参数呢?
- PathMeasure(Path path, boolean forceClosed) ;
第二个参数是用来确保 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();
- }
- }
第一个图大家学会了,去练习一下吧!
来源: http://www.phperz.com/article/17/0628/336127.html