android自定义view圆,Android自定义View圆形百分比控件(一)
做一个自定义View的小练习,效果如下
只需要画一个圆、一个圆弧、一个百分比文本,添加一个点击事件,传入百分比重绘
1、在res/values文件夹下新建attrs.xml文件,编写自定义属性:
2、新建CirclePercentView继承View,重写构造方法:
public CirclePercentView(Context context) {
this(context, null);
}
public CirclePercentView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CirclePercentView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
3、在第三个构造方法中获取自定义属性的值:
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CirclePercentView, defStyleAttr, 0);
mCircleColor = ta.getColor(R.styleable.CirclePercentView_circleBg, 0xff8e29fa);
mArcColor = ta.getColor(R.styleable.CirclePercentView_arcColor, 0xffffee00);
mArcWidth = ta.getDimensionPixelSize(R.styleable.CirclePercentView_arcWidth, DensityUtils.dp2px(context, 16));
mPercentTextColor = ta.getColor(R.styleable.CirclePercentView_arcColor, 0xffffee00);
mPercentTextSize = ta.getDimensionPixelSize(R.styleable.CirclePercentView_percentTextSize, DensityUtils.sp2px(context, 16));
mRadius = ta.getDimensionPixelSize(R.styleable.CirclePercentView_radius, DensityUtils.dp2px(context, 100));
ta.recycle();
4、创建画图所使用的对象,如Paint、Rect、RectF:
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setStyle(Paint.Style.FILL);
mCirclePaint.setColor(mCircleColor);
mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mArcPaint.setStyle(Paint.Style.STROKE);
mArcPaint.setStrokeWidth(mArcWidth);
mArcPaint.setColor(mArcColor);
mArcPaint.setStrokeCap(Paint.Cap.ROUND);//使圆弧两头圆滑
mPercentTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPercentTextPaint.setStyle(Paint.Style.STROKE);
mPercentTextPaint.setColor(mPercentTextColor);
mPercentTextPaint.setTextSize(mPercentTextSize);
mArcRectF = new RectF();//圆弧的外接矩形
mTextBound = new Rect();//文本的范围矩形
5、重写onMeasure()方法,计算自定义View的宽高:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureDimension(widthMeasureSpec), measureDimension(heightMeasureSpec));
}
private int measureDimension(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {//精确地,代表宽高为定值或者match_parent时
result = specSize;
} else {
result = 2 * mRadius;
if (specMode == MeasureSpec.AT_MOST) {//最大地,代表宽高为wrap_content时
result = Math.min(result, specSize);
}
}
return result;
}
6、重写onDraw()方法,绘制圆、圆弧和百分比文本,注意坐标的计算:
@Override
protected void onDraw(Canvas canvas) {
//画圆
canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mCirclePaint);
//画圆弧
mArcRectF.set(getWidth() / 2 - mRadius + mArcWidth / 2, getHeight() / 2 - mRadius + mArcWidth / 2
, getWidth() / 2 + mRadius - mArcWidth / 2, getHeight() / 2 + mRadius - mArcWidth / 2);
canvas.drawArc(mArcRectF, 270, 360 * mCurPercent / 100, false, mArcPaint);
String text = mCurPercent + "%";
//计算文本宽高
mPercentTextPaint.getTextBounds(text, 0, String.valueOf(text).length(), mTextBound);
//画百分比文本
canvas.drawText(text, getWidth() / 2 - mTextBound.width() / 2
, getHeight() / 2 + mTextBound.height() / 2, mPercentTextPaint);
}
7、给这个view设置点击事件,暴露一个动态设置百分比的方法:
public void setCurPercent(float curPercent) {
ValueAnimator anim = ValueAnimator.ofFloat(mCurPercent, curPercent);
//动画时长由百分比大小决定
anim.setDuration((long) (Math.abs(mCurPercent - curPercent) * 20));
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
mCurPercent = (float) (Math.round(value * 10)) / 10;//四舍五入保留到小数点后两位
invalidate();//重绘,重走onDraw()方法,这也是不能再onDraw()中创建对象的原因
}
});
anim.start();
}
public void setOnCircleClickListener(OnClickListener onClickListener) {
this.mOnClickListener = onClickListener;
}
//在构造方法中
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnClickListener != null) {
mOnClickListener.onClick(CirclePercentView.this);
}
}
});
8、在activity_main.xml布局文件中使用该View:
xmlns:cpv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/circlePercentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
cpv:arcColor="#ffee00"
cpv:arcWidth="@dimen/activity_horizontal_margin"
cpv:circleBg="#8e29fa"
cpv:percentTextColor="#ffee00"
cpv:percentTextSize="16sp"
cpv:radius="100dp" />
9、在MainActivity.java中设置监听,传入百分比:
mCirclePercentView = (CirclePercentView) findViewById(R.id.circlePercentView);
mCirclePercentView.setOnCircleClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
float percent = (float) (Math.random() * 99 + 1);
mCirclePercentView.setCurPercent(percent);
}
});
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
android自定义view圆,Android自定义View圆形百分比控件(一)相关推荐
- Android 自定义 圆环,一步步做Android自定义圆环百分比控件
马上要校招了,有点儿慌,写个自定义控件压压惊 效果图 本来写了一大串近段时间的感慨,还是觉得废话少说比较不容易被喷,直接上效果图 圆环百分比View.gif 就是这个样子,下面记录一下我的编写经历,撸 ...
- android多个水波球,android球形水波百分比控件代码
本文主要介绍的是一个球形水波的百分比控件,市面上有各种形形色色的百分比控件,我一直觉得水波是最炫的,UI给了我这个机会,然而网上搜了一大堆,不是太复杂,代码太多(反正我是调不出效果来),就是有瑕疵的, ...
- Android开发 入门篇(二) - 常用UI控件
文章目录 控件 Button TextView EditText ImageView ProgressBar AlertDialog ProgressDialog 布局 LenearLayout an ...
- Android之RemoteViews篇上————通知栏和桌面小控件
Android之RemoteViews篇上----通知栏和桌面小控件 一.目录 文章目录 Android之RemoteViews篇上----通知栏和桌面小控件 一.目录 二.RemoteViews的概 ...
- Android获取景点的信息,景点介绍(ListView控件应用)
1. 案例概述 此案例主要是对ListView列表控件的使用.当应用中包含多项数据,每项数据结构相同,只是内容不同时,可通过列表显示.对于列表中的内容,可以是显示字符串的TextView,也可以是结构 ...
- android menu item 显示,Android 如何通过menu id来得到menu item 控件 .
Android 如何通过menu id来得到menu item 控件 . (2012-07-21 06:43:31) 标签: android 如何 杂谈 Android 如何通过menu id来得到m ...
- android学习笔记---50_样式与主题,给控件使用样式,给应用使用主题
50_样式与主题 android学习笔记---50_样式与主题,给控件使用样式,给应用使用主题 2013/5/12 50_样式与主题 ----------------- android样式和主题(st ...
- 《深入理解Android 卷III》第六章 深入理解控件(ViewRoot)系统
<深入理解Android 卷III>即将发布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...
- 给DataList分页有两个办法:1、自定义实现分页方法 2、用第三方控件(例如AspNetPager)
给DataList分页有两个办法:1.自定义实现分页方法 2.用第三方控件(例如AspNetPager) 先介绍下如何自定义实现分页方法. 我的DataList分页方法的核心原理是利用PagedDat ...
最新文章
- Linux之 手动释放内存
- Mysql主从异常 表被回滚_oracle表回滚到一个指定时间的操作语句 oracle 误删除数据恢复...
- TComboBox下拉取值
- redis api-zset
- Struts2_4_ActionMap与ValueStack详解_Struct2的EL及常用标签_防止表单数据重复提交
- 【教程】一步一步教你如何自定义设置——博客园canvas/JS交互动画背景
- C++ STL min_element和max_element的使用方法
- 64位 setupdienumdeviceinterfaces_win7 32位重装系统详细教程
- SSH与FTP之间的关系与区别
- 如何制作一份高大上的学术PPT?
- macOS禁用指定应用联网的方法
- Excel:把数据生成曲线图
- 分享教程,制作Srt字幕最简单的方法
- git报错unsafe repository xxx is owned by someone else
- 使用163邮箱发送邮件报错(554, b'DT:SPM 163 smtp3,G9xpCgCHi5RJOFVemMZ4Dw--.348S3 1582643274,please see http://ma
- 【SQL】遍历字符串之Substr
- Spring事务抛出Exception异常不回滚
- 渠道面前,SaaS露出“素颜”
- 第十六届全国大学生智能车竞赛线上全国总决赛裁判手册
- 计算机组成原理(计算机硬件)