Android自定义view实现圆形waveview

最近学习了贝塞尔曲线的一些知识,刚好项目中需要实现一个圆形进度,然后就将实现的waveView记录一下。需要使用的知识大概有自定义view、贝塞尔曲线、valueAnimator(属性动画)、Xfermode等。
以下为效果图:

废话不多说,直接上代码这里只是一些重要的代码。如果需要demo可以去下载。
下载地址

首先需要自定义view的属性:

           //圆的颜色           //圆的背景色           //水波纹的颜色       //字体的大小              //字体的颜色

第二步自定义CustomWaveView

1、实现构造方法,在构造方法中获取属性值

TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.custom_wave_view_attr);//圆的颜色circle_color =        ta.getColor(R.styleable.custom_wave_view_attr_circle_color,getResources().getColor(android.R.color.black));//圆的背景色circle_bg_color =   ta.getColor(R.styleable.custom_wave_view_attr_circle_background_color,getResources().getColor(android.R.color.white));//水波纹颜色wave_color = ta.getColor(R.styleable.custom_wave_view_attr_progress_wave_color,getResources().getColor(android.R.color.holo_blue_dark));//字体的颜色text_color = ta.getColor(R.styleable.custom_wave_view_attr_progress_text_color,getResources().getColor(android.R.color.black));//字体的大小textSize = ta.getDimension(R.styleable.custom_wave_view_attr_progress_text_size,30f);//释放资源ta.recycle();

2、初始化画笔

//初始化背景圆画笔mBgCirclePaint = new Paint();//抗锯齿mBgCirclePaint.setAntiAlias(true);//设置背景圆的背景色mBgCirclePaint.setColor(circle_bg_color);//设置充满mBgCirclePaint.setStyle(Paint.Style.FILL);//初始化水波纹画笔mWavePaint = new Paint();//抗锯齿mWavePaint.setAntiAlias(true);//设置水波纹的背景色mWavePaint.setColor(wave_color);//设置充满mWavePaint.setStyle(Paint.Style.FILL);//使用Xfermode获取重叠部分mWavePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

3、绘制贝塞尔曲线。以下为原理图。

/*** 初始化贝塞尔曲线上的点*/private void reset() {    startP = new PointF(-width, height);    nextP = new PointF(-width/2, height);    threeP = new PointF(0, height);    fourP = new PointF(width/2, height);    endP = new PointF(width, height);    controllerP1 = new PointF(-width/4, height);    controllerP2 = new PointF(-width * 3/4, height);    controllerP3 = new PointF(width/4, height);    controllerP4 = new PointF(width * 3/4, height);}

4、在onDraw方法中画贝塞尔曲线和圆

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    //在透明画布上画背景圆    mCanvas.drawCircle(width/2, height/2, radius, mBgCirclePaint);    //贝塞尔曲线    mPath.reset();    mPath.moveTo(startP.x, startP.y);    mPath.quadTo(controllerP1.x, controllerP1.y, nextP.x, nextP.y);    mPath.quadTo(controllerP2.x, controllerP2.y, threeP.x, threeP.y);    mPath.quadTo(controllerP3.x, controllerP3.y, fourP.x, fourP.y);    mPath.quadTo(controllerP4.x, controllerP4.y, endP.x, endP.y);    mPath.lineTo(endP.x, height);    mPath.lineTo(-width, height);    //在透明画布上绘制水波纹    mCanvas.drawPath(mPath,mWavePaint);    //将画好的圆绘制在画布上    canvas.drawBitmap(mBitmap, 0, 0, null);}

5、使用动画让贝塞尔曲线动起来

/*** 开始动画 让startP的x点坐标在2S时间内循环移动到0点。*  depth---进度*  waveRipple----水波纹的振幅*/private void startAnimator() {    animator = ValueAnimator.ofFloat(startP.x, 0);    animator.setInterpolator(new LinearInterpolator());    animator.setDuration(2000);    //重复循环    animator.setRepeatCount(ValueAnimator.INFINITE);    animator.addUpdateListener(new       ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {       startP.x = (Float) animation.getAnimatedValue();       startP = new PointF(startP.x, height - depth);       nextP = new PointF(startP.x + width/2, height - depth);       threeP = new PointF(nextP.x + width/2, height - depth);       fourP = new PointF(threeP.x + width/2, height - depth);       endP = new PointF(fourP.x + width/2, height - depth);       controllerP1 = new PointF(startP.x + width/4, height - depth + waveRipple);       controllerP2 = new PointF(nextP.x + width/4, height - depth - waveRipple);       controllerP3 = new PointF(threeP.x + width/4, height - depth + waveRipple);       controllerP4 = new PointF(fourP.x + width/4, height - depth - waveRipple);       invalidate();    } }); animator.start();}

第三步在XML中使用自定义View

"@+id/custom_circle_wave_view"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        wave:circle_color = "@color/circle_color"        android:layout_centerInParent="true"        wave:circle_background_color = "@color/circle_bg_color"        wave:progress_wave_color = "@color/colorAccent"        wave:progress_text_size = "20sp"        wave:progress_text_color = "@color/circle_color"/>

这样就完成了自定义WaveView

更多相关文章

  1. android简易画图板与五子棋
  2. Android非UI线程中更新UI界面
  3. Android(安卓)Design Support Library(3)- Snackbar的使用
  4. android中在java代码中设置Button按钮的背景颜色
  5. Android(安卓)简单音乐播放器开发
  6. android在代码里设置button或者textView的字体颜色
  7. Android(安卓)Canvas绘制直方图
  8. Android控件之Textview
  9. WorkManager流程分析和源码解析

随机推荐

  1. 将所有域添加到CORS的安全隐患(Access-Con
  2. python正则表达式
  3. 某老师给我的javascript学习建议
  4. AngularJS:TypeError:无法读取未定义的属性
  5. 前端开发命名规范(html+css+js)
  6. Javascript / Jquery中的简单碰撞检测?
  7. 在contenteditable中的占位符—焦点事件
  8. CasperJs和Jquery用链式选择
  9. 当函数在单独的PHP文件中定义时,调用JavaS
  10. 用javascript 禁止右键,禁止复制,禁止粘