首先说一些,自定义view的话一般会重写一下三个方法:
onDraw(): 是用来绘制View图像,这个方法必须有.
onMeasure(): 用于改变View 的大小。
onLayout(): 用于改变View在父控件中的位置
Ok,继续.
(1).确定待画里面圆形以及矩形的位置
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int viewWidth = getMeasuredWidth();
int viewHeight = getMeasuredHeight();
mViewCenterX = viewWidth / 2;
mViewCenterY = viewHeight / 2;
mRectF = new RectF(mViewCenterX - mMinRadio - mRingWidth / 2, mViewCenterY - mMinRadio - mRingWidth / 2, mViewCenterX + mMinRadio + mRingWidth / 2, mViewCenterY + mMinRadio + mRingWidth / 2);
(2).绘制圆环
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(mMinCircleColor);
canvas.drawCircle(mViewCenterX, mViewCenterY, mMinRadio, mPaint);
drawNormalRing(canvas);
drawColorRing(canvas);
* 画默认圆环
* @param canvas
private void drawNormalRing(Canvas canvas) {
Paint ringNormalPaint = new Paint(mPaint);
ringNormalPaint.setStyle(Paint.Style.STROKE);
ringNormalPaint.setStrokeWidth(mRingWidth);
ringNormalPaint.setColor(mRingNormalColor);
canvas.drawArc(mRectF, 360, 360, false, ringNormalPaint);
* 画彩色圆环
* @param canvas
private void drawColorRing(Canvas canvas) {
Paint ringColorPaint = new Paint(mPaint);
ringColorPaint.setStyle(Paint.Style.STROKE);
ringColorPaint.setStrokeWidth(mRingWidth);
ringColorPaint.setShader(new SweepGradient(mViewCenterX, mViewCenterX, color, null));
canvas.rotate(-90, mViewCenterX, mViewCenterY);
canvas.drawArc(mRectF, 360, mSelectRing, false, ringColorPaint);
ringColorPaint.setShader(null);
ok,代码中的注释已经很详细了,我就不再细说了.
我只想说一下,代码中在绘制彩色圆环的时canvas.rotate(-90, mViewCenterX, mViewCenterY);注释中已经说了左边旋转90度.那么问题来了为什么要逆时针旋转90度呢?
这个是因为在后面画渐变色的圆弧时,drawArc和SweepGradient这两个类的起始点0度不是在我们习惯的圆环最上面那个点,而是从圆环最右边那个点开始,所以逆时针旋转90度就能让它从最上面的点开始.
盗图演示:
这下明白了吧.如果你还体会不深刻的话,就让你看一下,假如不逆时针旋转90度的话,是什么样的效果吧.
看到需要逆时针旋转90度的区别了吧.
通过上述步骤我们所需的圆环基本完成了.但是,要知道,画圆环不是目的,目的是让圆环去传表达或者描述一些信息,常用的场景,比如用来显示计步器的步数,显示文件下载的完成度等等.因此我们可以适当的添加点监听事件.
/**
* 设置当前值
* @param value
public void setValue(int value,TextView textView) {
if (value > mMaxValue) {
value = mMaxValue;
int start = 0;
int end = value;
startAnimator(start, end, 2000,textView);
private void startAnimator(int start, int end, long animTime, final TextView textView) {
valueAnimator = ValueAnimator.ofInt(start, end);
valueAnimator.setDuration(animTime);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Log.i(TAG, "onAnimationUpdate: animation.getAnimatedValue()::"+animation.getAnimatedValue());
int i = Integer.valueOf(String.valueOf(animation.getAnimatedValue()));
textView.setText(i + "");
mSelectRing=(int) (360 * (i / 100f));
Log.i(TAG, "onAnimationUpdate: mSelectRing::"+mSelectRing);
invalidate();
});
valueAnimator.start();
主程序 MainActivity.java:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
SuperCircleView mSuperCircleView;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.tv);
mSuperCircleView = findViewById(R.id.superview);
mSuperCircleView.setValue(100, textView);
mSuperCircleView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i = new Random().nextInt(100) + 1;
Log.i(TAG, "onClick: i::" + i);
mSuperCircleView.setValue(i, textView);
});
上述代码中设计属性动画ValueAnimator的相关知识,有兴趣的同学自己学习下.
好了,至此,自定义圆环结束.如果有疑问的话,请留言.诺诺的说一句,如果你感觉这篇文章写的还行的话,请给个赞.我感觉我需要被鼓励,哈哈,开玩笑的…
附上示例:
https://download.csdn.net/download/zhangqunshuai/10486568
参考文章:
一步步做Android自定义圆环百分比控件
Android自定义View的官方套路
Android 自定义view实现圆环
//绘制路径: 绘制一个圆环
private void doDrawPath(){
Bitmap.Config mConfig=mConfig = Bitmap.Config.ARGB_8888;
Bitmap bm = Bitmap.createBitmap(400,400,mConfig);
Canvas canvas = new Canvas(bm)
Canvas类中自带画圆弧函数:
public void drawArc (RectF oval,float
startAngle, float sweepAngle, boolean useCenter, Paint paint)
重点说明下关于角度的两个参数:
startAngle:圆弧是按顺时针画的,角度0与几何中0度的位置相同,即三点钟位置。但几何学中的逆时针方向角度从0到360
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入
欢迎使用Markdown编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar
一、实现效果图二、核心代码1.自定义MyProgressView.javapackage com.czhappy.effectdemo.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Bit...
    如果你想读懂或者更好的理解本篇文章关于自定义圆环或圆弧的内容.请你务必提前阅读下Android自定义View之画圆环(手把手教你如何一步步画圆环).在这篇文章中,详细描述了最基本的自定义圆环的绘
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 底层圆;宽高属性在 api 23以上有效;一旦生效,若与目标view的宽高不一致,那看到的效果就不正常;
可以去掉 宽高配置,在目标view上配置上 相同的 宽高就行 -->
android:wid
<?xml version="1.0" encoding="utf-8"?><?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/