Android初级进阶之自定义View之SafeVeiw
来源:互联网 发布:sql 统计每小时记录 编辑:程序博客网 时间:2024/05/17 22:20
SafeView
这是我模仿的一个效果,要不断的进步,就要不断的学习。主要实现的效果是一个转动的效果和一个3D触摸效果。请看效果图(录制的图片有点大):
知识点
1. Canvas2. Paint3. Shader4. Camera(不是相机)5. Animator
分析
整个View看上去是有四个圆组成,内中心的圆对边上有一个小圆,圆上面还有小尾巴。其实主要的原理是使用ValueAnimator来发散一个圆周的值,也就是360度,然后每次发散后旋转画布就能得到上面的效果。
技术点
- android.graphics.Camera是Android官方提供的3D效果组件,使用起来十分的简单,关键在于理解其中的x,y,z轴。(有空再写一篇Camera的使用)
Sharder 阴影渲染
- 本View中主要使用了LinearGradient和RadialGradient。
- LinearGradient为线性渐变,在这里主要是用来画小圆的尾巴。
- RadialGradient为径向渐变,从圆心向外四周扩散,在这里是用来画中心圆的效果。
- 本View中主要使用了LinearGradient和RadialGradient。
Animator 自3.0后推出的属性动画,本文主要使用ValueAnimator。
CODE
1.初始化 && Measure
将一些全局的值在构方法中进行初始化并且测量View的宽高等。
mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStrokeCap(Paint.Cap.ROUND);// 圆角笔触 mLeftLinearGradient = new LinearGradient(0, 0, mCy - OFFSET, mCy - OFFSET, 0xddffffff, 0x00000000, Shader.TileMode.CLAMP);//左边的尾巴 mRightLinearGradient = new LinearGradient(mCy - OFFSET, mCy / 2, 0, mCy / 2, 0xddffffff, 0x00000000, Shader.TileMode.CLAMP);//右边的尾巴
2.绘制所有的背景圆
圆的颜色是从中心开始不断的淡化的,其实这只要更改透明度就可以完成这样的效果
/** * @param canvas * @param radius 直径 * @param angle 当前角度 */private void canvasCircle(Canvas canvas, int radius, float angle) { float percentage = angle / 360f;//当前角度百分比 mPaint.setColor(0xddffffff); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(1.5f); //绘制中心圆圈 canvas.drawCircle(radius, radius, radius - OFFSET, mPaint); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(0x22ffffff); if (aninatopValue >= 90) { //绘制第二圆圈 canvas.drawCircle(radius, radius, radius - OFFSET + 40 * percentage, mPaint); } mPaint.setColor(0x11ffffff); if (aninatopValue >= 180) { //绘制第三圆圈 canvas.drawCircle(radius, radius, radius - OFFSET + 80 * percentage, mPaint); } if (aninatopValue >= 270) { //绘制第四圆圈 canvas.drawCircle(radius, radius, radius - OFFSET + 120 * percentage, mPaint); } if (aninatopValue <= 90) {// 初始状态下绘制所有的圆圈 mPaint.setColor(0x22ffffff); canvas.drawCircle(radius, radius, radius - OFFSET + 40, mPaint); mPaint.setColor(0x11ffffff); canvas.drawCircle(radius, radius, radius - OFFSET + 80, mPaint); canvas.drawCircle(radius, radius, radius - OFFSET + 120, mPaint); } mPaint.setColor(0xff1782dd);//绘制中心圆为背景颜色 canvas.drawCircle(radius, radius, radius - OFFSET, mPaint); mPaint.setColor(0x55ffffff); //渲染 得到中心的 凹凸效果 RadialGradient radialGradient = new RadialGradient(radius, radius, radius - OFFSET, new int[]{0x00000000, 0xffffffff}, null, Shader.TileMode.CLAMP); mPaint.setShader(radialGradient); canvas.drawCircle(radius, radius, radius - OFFSET, mPaint);}
效果图:
3.绘制中间的文字
/** * //绘制文字 * * @param canvas * @param radius */private void canvasText(Canvas canvas, int radius) { mPaint.setShader(null);//文字颜色 mPaint.setColor(0x88ffffff);//转换字体 mPaint.setTextSize(DensityUtils.sp2px(getContext(), 14)); mPaint.setStrokeWidth(2); mPaint.setStyle(Paint.Style.STROKE); String safeText = "已防御次数"; canvas.drawText(safeText, radius - mPaint.measureText(safeText) / 2, (radius - mPaint.measureText(String.valueOf(safeText)) / 2), mPaint); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(0xffffffff); mPaint.setTextSize(DensityUtils.sp2px(getContext(), 30)); mPaint.setStrokeWidth(2); canvas.drawText(String.valueOf(safeCount), radius - mPaint.measureText(String.valueOf(safeCount)) / 2, radius + radius / 4, mPaint);}
4.绘制左右两个圆点并旋转
到这里,基本绘制就已经完成了,只要加上角度的计算和动画部分,这个View就能够动起来了。
/** * 绘制旋转部分 */private void canvasRotate(Canvas canvas, int radius, float angle) { //旋转画布 canvas.rotate(angle, radius, radius); //移动坐标到中心 canvas.translate(radius, radius); mPaint.setShader(null); //左边的圆 mPaint.setColor(Color.WHITE); mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeWidth(5); canvas.drawCircle(-radius + OFFSET, 0, 10, mPaint); //右边的圆 canvas.drawCircle(radius - OFFSET, 0, 10, mPaint); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(8); //绘制坐标的圆的尾巴 RectF mRectF = new RectF(-radius + OFFSET, -radius + OFFSET, radius - OFFSET, radius - OFFSET); mPaint.setShader(mRightLinearGradient); canvas.drawArc(mRectF, 15, 180 - 15, false, mPaint); mPaint.setShader(mLeftLinearGradient); canvas.drawArc(mRectF, 180 + 15, 180 - 15, false, mPaint); //合并画布 canvas.restore();}
5.动画与角度
/** * 开始 */private void startLoopAnimator() { //发散350度 motionAnimator = ValueAnimator.ofFloat(360f).setDuration(1500); //线性差值器 motionAnimator.setInterpolator(new LinearInterpolator()); //永远循环 motionAnimator.setRepeatCount(ValueAnimator.INFINITE); motionAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { safeCount++; aninatopValue = (float) animation.getAnimatedValue(); postInvalidate(); } }); motionAnimator.start();}
最后
源码
阅读全文
0 0
- Android初级进阶之自定义View之SafeVeiw
- Android初级进阶之自定义时钟(一)
- Android初级进阶之自定义时钟(二)
- [android进阶]自定义View之TopBar
- Android开发进阶之自定义view
- Android 自定义View绘图篇之进阶
- Android进阶之自定义view(一)
- Android进阶之自定义view(二)
- Android进阶之自定义view(三)
- Android进阶之自定义view(四)
- Android 自定义View动画篇之进阶
- 【Android进阶之自定义View(一)】
- 【Android进阶之自定义View(二)】
- 【Android进阶之自定义View(三)】
- Android初级进阶之Shape
- Android小白进阶(三)--自定义控件之自定义View
- android进阶之自定义view(文字圆形边框)
- Android进阶——自定义View之扩展系统Dialog
- AndroidStudio使用Material Theme UI
- 使用BeanUtils操作Javabean
- linux——创建
- node.js 的express服务器报 413 payload too large
- 传输层协议(TCP/UDP)学习总结
- Android初级进阶之自定义View之SafeVeiw
- 计蒜客-单独的数字+求平方根
- 逻辑回归原理介绍及Matlab实现
- opencv开发笔记(十五):特征检测十大方法之SURF算法
- 如何在线免费将MP4转换成MP3格式音乐
- Shiro 的身份认证-Realm
- 关于AppCompatSpinner在某些机型使用popupBackground显示异常的解决方案
- 如何判断Javascript对象是否存在
- 【Java集合类】Vector解析