Android杂谈(21)补坑+Path动画
来源:互联网 发布:淘宝网京东商城茅台酒 编辑:程序博客网 时间:2024/06/01 09:11
转载请注意:http://blog.csdn.net/wjzj000/article/details/59112306
本菜开源的一个自己写的Demo,希望能给Androider们有所帮助,水平有限,见谅见谅…
https://github.com/zhiaixinyang/PersonalCollect (拆解GitHub上的优秀框架于一体,全部拆离不含任何额外的库导入)
https://github.com/zhiaixinyang/MyFirstApp(Retrofit+RxJava+MVP)
写在前面
来到学校接近一周的时间算是啥也没干,这篇博客便是打响武装反抗惰性学习第一枪。
之前写过一篇博客:http://blog.csdn.net/wjzj000/article/details/53929870
是关于官方的侧滑控件DrawerLayout,它本身的用法比较简单。只是我隐隐约约记得之前留了一个坑:那个可以动的控制侧滑菜单打开关闭的按钮。
正好结合这Path动画,把这个坑填上。
填坑
上篇博客中使用的有动画效果的箭头是来自:https://github.com/ChrisRenke/DrawerArrowDrawable
的开源作品,具体的使用方式,各位看官可以移步这位大神的GitHub上,一睹傲视武林一统江湖的王者之霸气。
这里简单梳理一下源码,然后进去本次博客想记录的核心Path动画。
public DrawerArrowDrawable(Resources resources, boolean rounded) { this.rounded = rounded; float density = resources.getDisplayMetrics().density; float strokeWidthPixel = STROKE_WIDTH_DP * density; halfStrokeWidthPixel = strokeWidthPixel / 2; linePaint = new Paint(SUBPIXEL_TEXT_FLAG | ANTI_ALIAS_FLAG); linePaint.setStrokeCap(rounded ? ROUND : BUTT); linePaint.setColor(BLACK); linePaint.setStyle(STROKE); linePaint.setStrokeWidth(strokeWidthPixel); int dimen = (int) (DIMEN_DP * density); bounds = new Rect(0, 0, dimen, dimen); Path first, second; JoinedPath joinedA, joinedB; // 按钮的第一条线的相关路径操作 first = new Path(); first.moveTo(5.042f, 20f); // 三阶贝塞尔曲线:说白了就是给定四个坐标点(moveTo为起始点,rCubicTo分别代表第一个控制点,第二个控制点,结束的点),系统通过贝塞尔方程画出一个线来。 first.rCubicTo(8.125f, -16.317f, 39.753f, -27.851f, 55.49f, -2.765f); second = new Path(); second.moveTo(60.531f, 17.235f); second.rCubicTo(11.301f, 18.015f, -3.699f, 46.083f, -23.725f, 43.456f); //将路径缩放到给定的屏幕密度。(让按钮大小适配屏幕) scalePath(first, density); scalePath(second, density); joinedA = new JoinedPath(first, second); //省略大量类似代码 }
从这里我们基本可以看出,作者是直接使用多个Path来完成效果。
其中通过PathMeasure每个Path上的每个点的坐标位置,然后不断的重新绘制线段。
作者通过,如下代码进行回调,请求重绘:
new DrawerLayout.SimpleDrawerListener() { @Override public void onDrawerSlide(View drawerView, float slideOffset) { offset = slideOffset; if (slideOffset >= .995) { flipped = true; drawerArrowDrawable.setFlip(flipped); } //省略部分代码
public void setFlip(boolean flip) { this.flip = flip; invalidateSelf();}
回调产生以后,就会调用作者封装的draw方法:
private void draw(Canvas canvas) { pathA.getPointOnLine(parameter, coordsA); pathB.getPointOnLine(parameter, coordsB); if (rounded) insetPointsForRoundCaps(); //coordsA当前路线的坐标,通过PathMeasure的getPosTan方法获得。 canvas.drawLine(coordsA[0], coordsA[1], coordsB[0], coordsB[1], linePaint);}
通过PathMeasure的getPosTan获取中Path的多点坐标,然后重新绘制线段。完成动态效果。
OK,关于填坑,就到这里了。因为作者的源码比较的长。所以各位看官如果感兴趣的话,可以自己移步作者的GitHub之上就查看源码。
作者继承了android.graphics.drawable.Drawable来完成这个效果:
关于Drawable的官方解释:
Drawable是“可以绘制的东西”的一般抽象。通常你会处理Drawable作为绘制东西到屏幕上检索的资源类型; Drawable类提供了一个通用的API来处理可能采取各种形式的底层视觉资源。与View不同,Drawable没有任何功能来接收事件或与用户交互。
Path动画
接下来的内容是结合ValueAnimator结合Path实现动态的Path效果。
先看一下效果:
直接上代码:
初始化Path和Paint:
paint = new Paint();paint.setColor(Color.DKGRAY);paint.setStrokeWidth(10);paint.setStyle(Paint.Style.STROKE);path = new Path();path.moveTo(50, 50);for (int i = 0; i < 4; i++) { path.lineTo(450 - i * 50, 50 + i * 50); path.lineTo(450 - i * 50, 450 - i * 50); path.lineTo(50 + i * 50, 450 - i * 50); path.lineTo(50 + i * 50, 100 + i * 50);}
setPathEffect:
PathMeasure measure = new PathMeasure(path, false); length = measure.getLength(); animator = ValueAnimator.ofFloat(0.0f, 1.0f); animator.setDuration(5000); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float fraction = animation.getAnimatedFraction(); //这里使用了一个DashPathEffect的技巧 paint.setPathEffect(createPathEffect(length, fraction)); postInvalidate(); } }); animator.start();private static PathEffect createPathEffect(float pathLength, float phase) { return new DashPathEffect(new float[]{pathLength, pathLength}, pathLength - phase * pathLength); }
我们在new DashPathEffect的时候传入的间隔值就是Path的全长,因此这里是没有间断的。我们控制Path的动画,实际是控制DashPathEffect的偏移,也就是pathLength - phase * pathLength,这个值是从Path全长随动画的进度逐渐减小到0。
对应到我们的效果之上就是Path从什么都没有,然后知道全部展现。(因为此时的偏移为0)
onDraw()中很简单,就是调用drawPath:
@Override public void onDraw(Canvas c) { super.onDraw(c); c.drawPath(path, paint); }
原理非常的简单,我们可以理解是使用了DashPathEffect的错位效果。我们都知道DashPathEffect的一般制作效果是波浪线。
而这里我们使用它的偏移属性,做到了线段追逐的效果。
因为需要动态更新效果,所以使用动画进行控制。
PS:相关源码基本都存放于我的这个开源项目之中:
https://github.com/zhiaixinyang/PersonalCollect
尾声
OK,坑到这也填的差不多了。
学习虽好,但不要贪杯。有情不必终老,暗香浮动恰好。
最后希望各位看官可以star我的GitHub,三叩九拜,满地打滚求star:
https://github.com/zhiaixinyang/PersonalCollect
https://github.com/zhiaixinyang/MyFirstApp
- Android杂谈(21)补坑+Path动画
- Android 动画杂谈(一)
- Android 动画杂谈 (三)
- Android tween动画(补间动画)
- android动画之:补间动画(Tween动画)
- Android 动画(一)帧动画、补间动画
- Android属性动画和View动画(补间动画)
- Android 动画总结(补间动画,属性动画)
- Android补间动画(TweenedAnimations)详解
- Android 补间动画解析(一)
- android补间动画(Tween Animation)
- android补间动画(TweenAnimation)
- android 补间(Tween)动画
- Android-补间动画
- Android-补间动画
- Android 补间动画
- Android补间动画
- Android 补间动画
- 并发系列文章
- 第一行代码笔记 全局获取context,定时任务,日志打印
- java基础.集合.properties.初识
- Android5 Lollipop 中关于 SELinux 安全机制调试笔记
- 访问maven项目总是报404
- Android杂谈(21)补坑+Path动画
- selenium+testng+gitblit+jenkins+ant自动化测试系列六:eclipse上传代码到服务器
- 4. Median of Two Sorted Arrays
- java自带工具keytool生成keystore
- JavaIO输入输出流的总结
- eclipse jni 编译第三方.a文件报错
- 页面制作之调试工具
- 洛谷 P1273 有线电视网
- 响应式编程在Android中的应用