Android自定义View之CircleView
Android自定义View之CircleView
版权声明:本文为博主原创文章,未经博主允许不得转载。
前言
大家好,我是Cavalier,这次和大家分享一下《Android自定义View之CircleView》,不废话,下面上效果图。

分析
需求
1:随机换颜色的一个view
2:可以设置文字
动手
Setup1:继承自View,重写三个构造函数
public class CircleView extends View {
public CircleView(Context context) {
this(context,null);
}
public CircleView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
上面代码中重写了三个构造函数,其中第一个是用于直接new对象,第二个是从xml创建时没有指定style时调用,第三个是指定了style时调用,通过this可以直接指向第三个构造参数,所有初始化可以直接写在第三个构造参数中
Setup2:声明所需的变量
private Paint mTextPain; //初始化画笔
private String mText = ""; //初始化文字
private int radius; //当前View的半径
...
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
configPaint();
}
private void configPaint() {
mTextPain = new Paint();
mTextPain.setColor(Color.WHITE); //设置画笔颜色为白色
mTextPain.setAntiAlias(true); //开启抗锯齿,平滑文字和圆弧的边缘
mTextPain.setTextAlign(Paint.Align.CENTER); //设置文本位于相对于原点的中间
}
上面代码在第三个构造函数调用了configPaint函数
Setup3:重新onDraw函数
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth() / 2; //获取宽度一半
int height = getHeight() / 2; //获取高度一半
radius = Math.min(width, height); //设置半径为宽或者高的最小值
//paint bg
mTextPain.setColor(Color.parseColor(getRandomColor())); //设置画笔颜色为随机颜色
canvas.drawCircle(width, height, radius, mTextPain); //利用canvas画一个圆
//paint font
mTextPain.setColor(Color.WHITE); //设置画笔白颜色
mTextPain.setTextSize(dp2px(16)); //设置字体大小为16dp
Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //获取字体测量对象
canvas.drawText(mText, 0, mText.length(), radius //利用canvas画上字
, radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain);
}
上面代码中先获取到当前view的宽和高,取其中最小值作为背景的半径,设置了随机颜色做背景,且利用FontMetrics获取了文字的绘制位置
Setup4:添加两个辅助函数,dp2px和getRandomColor
/**
* 给View设置文字
* @param str
*/
public void setText(String str) {
if(!TextUtils.isEmpty(str)){
if(str.length()>1){
mText = str.substring(0,1);
}else {
mText = str;
}
}else {
mText = "";
}
invalidate();
}
当然,我们需要将设置文字暴露给使用者,这里利用了invalidate让CircleView重新绘制一遍,目的是更改内中的文字
Setup5:添加两个辅助函数,dp2px和getRandomColor
/**
* dp转px
*
* @param dp
* @return
*/
private int dp2px(int dp) {
// px = dp * (dpi / 160)
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
int dpi = metrics.densityDpi;
return (int) (dp * (dpi / 160f) + 0.5f);
}
/**
* 获取随机颜色
*
* @return
*/
private String getRandomColor() {
List<String> colorList = new ArrayList<String>();
colorList.add("#303F9F");
colorList.add("#FF4081");
colorList.add("#59dbe0");
colorList.add("#f57f68");
colorList.add("#f8b552");
colorList.add("#990099");
colorList.add("#90a4ae");
colorList.add("#7baaf7");
colorList.add("#4dd0e1");
colorList.add("#4db6ac");
colorList.add("#aed581");
colorList.add("#fdd835");
colorList.add("#f2a600");
colorList.add("#ff8a65");
colorList.add("#f48fb1");
colorList.add("#7986cb");
colorList.add("#DEB887");
colorList.add("#FF69B4");
return colorList.get((int) (Math.random() * colorList.size()));
}
补充了这两个辅助函数后,代码已经完成了
How to use?
在XML中使用
...
<com.ram.testdemo.view.CircleView
android:id="@+id/cv"
android:layout_width="50dp"
android:layout_height="50dp"/>
...
这里注意调用时是使用你自己的Class文件全路径。
在java中使用
CircleView mCircleView = (CircleView) findViewById(R.id.cv);
mCircleView.setText("哈哈");
Souce Code
public class CircleView extends View {
private Paint mTextPain; //初始化画笔
private String mText = ""; //初始化文字
private int radius; //当前View的半径
public CircleView(Context context) {
this(context, null);
}
public CircleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
configPaint();
}
private void configPaint() {
mTextPain = new Paint();
mTextPain.setColor(Color.WHITE); //设置画笔颜色为白色
mTextPain.setAntiAlias(true); //开启抗锯齿,平滑文字和圆弧的边缘
mTextPain.setTextAlign(Paint.Align.CENTER); //设置文本位于相对于原点的中间
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth() / 2; //获取宽度一半
int height = getHeight() / 2; //获取高度一半
radius = Math.min(width, height); //设置半径为宽或者高的最小值
//paint bg
mTextPain.setColor(Color.parseColor(getRandomColor())); //设置画笔颜色为随机颜色
canvas.drawCircle(width, height, radius, mTextPain); //利用canvas画一个圆
//paint font
mTextPain.setColor(Color.WHITE); //设置画笔白颜色
mTextPain.setTextSize(dp2px(16)); //设置字体大小为16dp
Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //获取字体测量对象
canvas.drawText(mText, 0, mText.length(), radius //利用canvas画上字
, radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain);
}
/**
* 给View设置文字
* @param str
*/
public void setText(String str) {
if(!TextUtils.isEmpty(str)){
if(str.length()>1){
mText = str.substring(0,1);
}else {
mText = str;
}
}else {
mText = "";
}
invalidate();
}
/**
* dp转px
*
* @param dp
* @return
*/
public int dp2px(int dp) {
// px = dp * (dpi / 160)
DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
int dpi = metrics.densityDpi;
return (int) (dp * (dpi / 160f) + 0.5f);
}
/**
* 获取随机颜色
*
* @return
*/
private String getRandomColor() {
List<String> colorList = new ArrayList<String>();
colorList.add("#303F9F");
colorList.add("#FF4081");
colorList.add("#59dbe0");
colorList.add("#f57f68");
colorList.add("#f8b552");
colorList.add("#990099");
colorList.add("#90a4ae");
colorList.add("#7baaf7");
colorList.add("#4dd0e1");
colorList.add("#4db6ac");
colorList.add("#aed581");
colorList.add("#fdd835");
colorList.add("#f2a600");
colorList.add("#ff8a65");
colorList.add("#f48fb1");
colorList.add("#7986cb");
colorList.add("#DEB887");
colorList.add("#FF69B4");
return colorList.get((int) (Math.random() * colorList.size()));
}
}
结尾
本篇中,我们掌握了自定义View的invalidate重绘,和FontMetrics的文本位置测量,还了解onDraw中的canvas的用法。如文中有描述不巧当的地方请指出,谢谢。
Android自定义View之CircleView的更多相关文章
- Android自定义View 画弧形,文字,并增加动画效果
一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类 B ...
- (转)[原] Android 自定义View 密码框 例子
遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...
- Android 自定义View合集
自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...
- Android 自定义View (五)——实践
前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...
- Android 自定义 view(四)—— onMeasure 方法理解
前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...
- Android 自定义 view(三)—— onDraw 方法理解
前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...
- Android 自定义view(二) —— attr 使用
前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...
- Android 自定义View
Android 自定义View流程中的几个方法解析: onFinishInflate():从布局文件.xml加载完组件后回调 onMeasure() :调用该方法负责测量组件大小 onSizeChan ...
- Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程
转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...
随机推荐
- 在Windows和Linux上安装paramiko模块以及easy_install的安装方法
一.paramiko模块有什么用? paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.由于使用的是python这样的能够跨平台运行的语言 ...
- [MAC]用beamoff给VMware的Mac OS X 10.10.x加速
MAC OS X 10.10.x Yosemite在VMWare中实在是太慢了,卡出翔!好在高人多,请装beamoff!详见:https://github.com/JasF/beamoff.git C ...
- Linux如何查看进程、杀死进程、启动进程等常用命令
Linux如何查看进程.杀死进程.启动进程等常用命令 关键字: linux 查进程.杀进程.起进程1.查进程 ps命令查找与进程相关的PID号: ps a 显示现行终端机下的所有程序,包括 ...
- 如何优化cocos2d程序的内存使用和程序大小
在我完成第一个游戏项目的时候,我深切地意识到"使用cocos2d来制作游戏的开发者们,他们大多会被cocos2d的内存问题所困扰".而我刚开始接触cocos2d的时候,社区里面的人 ...
- innodb buffer pool小解
INNODB维护了一个缓存数据和索引信息到内存的存储区叫做buffer pool,他会将最近访问的数据缓存到缓冲区.通过配置各个buffer pool的参数,我们可以显著提高MySQL的性能. INN ...
- Netty
首先值得注意的是netty的jar包版本问题,版本不同,运用的方式也不同.我这里用4.0版本. 对于小白来说,netty到底是什么,我就没必要在这里阐明了,因为百度上比我描述的更全面. 这里就直接开门 ...
- LNMP添加、删除虚拟主机及伪静态使用教程
一般情况下每个虚拟主机就是一个网站,网站一般通过域名进行访问.LNMP 1.2的网站添加过程和LNMP 1.1的基本类似,但是增加了FTP和数据库的创建.LNMP1.2的防跨目录也由原来在php.in ...
- css中伪元素before或after中content的特殊用法attr
html代码如下: <div class="haorooms"> <span data-haorooms="haorooms鼠标效果tips-纯css& ...
- <一>Angular.js学习
angular.module(name, [a], [b]); // angular.module()创建.获取.注册angular中的模块 name:字符串类型,代表模块的名称: a:字符串的数组 ...
- [原创.数据可视化系列之六]使用openlyaers进行公网地图剪切
进行地图开发的过程中,我一般使用天地图或者微软的地图作为地图,因为这两种地图的经纬度偏差最小,基本可以满足用户需求,比如: 不用说,都是全部地图,这也是最常用的一种方法. 但是用户说,我只看大连的地图 ...