Android自定义View圆形进度条控件(三)

继续练习自定义View,这次带来的圆形进度条控件与之前的圆形百分比控件大同小异,这次涉及到了渐变渲染以及画布旋转等知识点,效果如下:

虽然步骤类似,但是我还是要写,毕竟基础的东西就是要多练

1、在res/values文件夹下新建attrs.xml文件,编写自定义属性:

<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CircleProgressView"> <!-- 弧线宽度 --> <attr name="arcWidth" format="dimension" /> <!-- 刻度个数 --> <attr name="scaleCount" format="integer" /> <!-- 渐变起始颜色 --> <attr name="startColor" format="color" /> <!-- 渐变终止颜色 --> <attr name="endColor" format="color" /> <!-- 标签说明文本 --> <attr name="labelText" format="string" /> <!-- 文本颜色 --> <attr name="textColor" format="color" /> <!-- 百分比文本字体大小 --> <attr name="progressTextSize" format="dimension" /> <!-- 标签说明字体大小 --> <attr name="labelTextSize" format="dimension" /> </declare-styleable> </resources>

2、新建CircleProgressView继承View,重写构造方法:

public CircleProgressView(Context context) { this(context, null); } public CircleProgressView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }

3、在第三个构造方法中获取自定义属性的值:

TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0); mArcWidth = ta.getDimension(R.styleable.CircleProgressView_arcWidth, DensityUtils.dp2px(context, 8)); mScaleCount = ta.getInteger(R.styleable.CircleProgressView_scaleCount, 24); mStartColor = ta.getColor(R.styleable.CircleProgressView_startColor, Color.parseColor("#3FC199")); mEndColor = ta.getColor(R.styleable.CircleProgressView_endColor, Color.parseColor("#3294C1")); mColorArray = new int[]{mStartColor, mEndColor}; mLabelText = ta.getString(R.styleable.CircleProgressView_labelText); mTextColor = ta.getColor(R.styleable.CircleProgressView_textColor, Color.parseColor("#4F5F6F")); mProgressTextSize = ta.getDimension(R.styleable.CircleProgressView_progressTextSize, 160); mLabelTextSize = ta.getDimension(R.styleable.CircleProgressView_labelTextSize, 64); ta.recycle();

4、创建画图所使用的对象,如Paint、Rect、RectF:

mArcBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mArcBackPaint.setStyle(Paint.Style.STROKE); mArcBackPaint.setStrokeWidth(mArcWidth); mArcBackPaint.setColor(Color.LTGRAY); mArcForePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mArcForePaint.setStyle(Paint.Style.STROKE); mArcForePaint.setStrokeWidth(mArcWidth); mArcRectF = new RectF(); mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLinePaint.setStyle(Paint.Style.STROKE); mLinePaint.setColor(Color.WHITE); mLinePaint.setStrokeWidth(DensityUtils.dp2px(context, 2)); mProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mProgressTextPaint.setStyle(Paint.Style.FILL); mProgressTextPaint.setColor(mTextColor); mProgressTextPaint.setTextSize(mProgressTextSize); mLabelTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLabelTextPaint.setStyle(Paint.Style.FILL); mLabelTextPaint.setColor(mTextColor); mLabelTextPaint.setTextSize(mLabelTextSize); mTextRect = new Rect();

5、重写onMeasure()方法,计算自定义View的宽高:

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measuredDimension(widthMeasureSpec), measuredDimension(heightMeasureSpec)); } private int measuredDimension(int measureSpec) { int result; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); if (mode == MeasureSpec.EXACTLY) { result = size; } else { result = 800; if (mode == MeasureSpec.AT_MOST) { result = Math.min(result, size); } } return result; }

6、重写onDraw()方法,绘制圆弧、刻度线和百分比文本、标签说明文本,注意坐标的计算:

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mArcRectF.set(mArcWidth / 2, mArcWidth / 2, getWidth() - mArcWidth / 2, getHeight() - mArcWidth / 2); //画背景弧线 canvas.drawArc(mArcRectF, -90, 360, false, mArcBackPaint); //设置渐变渲染 LinearGradient linearGradient = new LinearGradient(getWidth() / 2, 0, getWidth() / 2, getHeight(), mColorArray, null, Shader.TileMode.CLAMP); mArcForePaint.setShader(linearGradient); //画百分比值弧线 canvas.drawArc(mArcRectF, -90, mSweepAngle, false, mArcForePaint); //画刻度线 for (int i = 0; i < mScaleCount; i++) { canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mArcWidth, mLinePaint); //旋转画布 canvas.rotate(360 / mScaleCount, getWidth() / 2, getHeight() / 2); } //画百分比文本 String progressText = mProgress + "%"; mProgressTextPaint.getTextBounds(progressText, 0, progressText.length(), mTextRect); float progressTextWidth = mTextRect.width(); float progressTextHeight = mTextRect.height(); canvas.drawText(progressText, getWidth() / 2 - progressTextWidth / 2, getHeight() / 2 + progressTextHeight / 2, mProgressTextPaint); //画标签说明文本 mLabelTextPaint.getTextBounds(mLabelText, 0, mLabelText.length(), mTextRect); canvas.drawText(mLabelText, getWidth() / 2 - mTextRect.width() / 2, getHeight() / 2 - progressTextHeight / 2 - mTextRect.height(), mLabelTextPaint); }

7、暴露一个动态设置百分比的方法:

public void setProgress(float progress) { Log.e("--> ", progress + ""); ValueAnimator anim = ValueAnimator.ofFloat(mProgress, progress); anim.setDuration((long) (Math.abs(mProgress - progress) * 20)); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mProgress = (float) animation.getAnimatedValue(); mSweepAngle = mProgress * 360 / 100; mProgress = (float) (Math.round(mProgress * 10)) / 10;//四舍五入保留到小数点后两位 invalidate(); } }); anim.start(); }

8、在activity_main.xml布局文件中使用该View:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cpv="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <com.monkey.circleprogressview.CircleProgressView android:id="@+id/circle_progress_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" cpv:arcWidth="8dp" cpv:endColor="#126b94" cpv:labelText="学习进度" cpv:labelTextSize="20sp" cpv:progressTextSize="55sp" cpv:scaleCount="24" cpv:startColor="#12d699" cpv:textColor="#4F5F6F" /> </RelativeLayout>

9、在MainActivity中设置监听,传入百分比:

final CircleProgressView view = (CircleProgressView) findViewById(R.id.circle_progress_view); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { float progress = (float) (Math.random() * 100); view.setProgress(progress); } });

代码下载地址:
https://github.com/MonkeyMushroom/CircleProgressView/tree/master

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2017-11-29

Android自定义View圆形进度条控件(三)的相关文章

Android 自定义view实现进度条加载效果实例代码

这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

android ListView和ProgressBar(进度条控件)的使用方法_Android

ListView控件的使用:ListView控件里面装的是一行一行的数据,一行中可能有多列,选中一行,则该行的几列都被选中,同时可以触发一个事件,这种控件在平时还是用得很多的.使用ListView时主要是要设置一个适配器,适配器主要是用来放置一些数据.使用起来稍微有些复杂,这里用的是android自带的SimpleAdapter,形式如下:android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<

android ListView和ProgressBar(进度条控件)的使用方法

ListView控件的使用:ListView控件里面装的是一行一行的数据,一行中可能有多列,选中一行,则该行的几列都被选中,同时可以触发一个事件,这种控件在平时还是用得很多的.使用ListView时主要是要设置一个适配器,适配器主要是用来放置一些数据.使用起来稍微有些复杂,这里用的是android自带的SimpleAdapter,形式如下:android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<

Android自定义View简易折线图控件(二)

继续练习自定义View,这次带来的是简易折线图,支持坐标点点击监听,效果如下: 画坐标轴.画刻度.画点.连线..x.y轴的数据范围是写死的 1 <= x <= 7 ,1 <= y <= 70 ..写活的话涉及到坐标轴刻度的动态计算.坐标点的坐标修改,想想就头大,这里只练习自定义View. 1.在res/values文件夹下新建attrs.xml文件,编写自定义属性: <?xml version="1.0" encoding="utf-8"

Android自定义View弧线进度控件_Android

这个是一个以弧线为依托的进度控件,主要包括了两个圆弧.一个圆.一个文本.   当我们点击开始按钮的时候,会出现一个动画,逐渐的出现进度,好了,下面开始我们的编码. 新建一个类,继承自View,实现三个构造方法,接着定义变量,初始化变量的数据.代码如下: private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint; private float length; private float mRadius; private float mCirc

android自定义view-Android在自定义View控制Activity里控件

问题描述 Android在自定义View控制Activity里控件 最近在学习Android,想做一个效果遇到了困难.我自定义了一个View,然后在View里设置触摸事件,点击一个出现一个按钮, 再点击一下按钮消失.我不知道怎么在自定义View里添加Button,就放在了布局了.但是用在自定义View设置的点击事件来控 制布局里的按钮?跪谢跪谢. 解决方案 以下是在Activity里的操作 private Button bt1;//你的按钮控件 View myView=View.inflate(

VB 6.0的进度条控件怎么变成圆形的进度条

问题描述 VB 6.0的进度条控件怎么变成圆形的进度条 VB6.0的进度条怎么设置成圆形的进度条,类似迅雷下载的效果,并且在圆的中间显示数字的进度提示 解决方案 用imagelist,按照百分比绘制好图片,动态加载. 解决方案二: 自己编写vb进度条控件

新手问题--关于自定义进度条控件

问题描述 我接触c#不久,想做一个自定义的进度条控件,要求是能够实现平滑渐变效果(如从左边的红色平滑渐变到右边的绿色),如果可能的话,增加一个渐变方式的属性,从中可以选择两端的颜色.我想问一下设计的思路.谢谢了 解决方案 解决方案二:<html><head><title></title><scriptlanguage="javascript">//开始处理functionBeginTrans(msg){WriteText(&q

VB编写一个能显示百分比的自定义进度条控件

百分比|控件|显示 运行效果: 设计方法: 1.在UserControl中添加一个Label控件Label1,将它设为平面,用来做外框.添加两个PictureBox控件PictureBox1做为进度指示,PictureBox2控件做为控件背景. 2.加入以下代码 Option Explicit '定义私有变量用于存储属性值Private mvarMax As LongPrivate mvarMin As LongPrivate mvarValue As Long Private Rate As