Android自定义View之CircleView

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载请表明出处:http://www.cnblogs.com/cavalier-/p/5999037.html

前言

大家好,我是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 custom-components

Android自定义View之CircleView的更多相关文章

  1. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  2. (转)[原] Android 自定义View 密码框 例子

    遵从准则 暴露您view中所有影响可见外观的属性或者行为. 通过XML添加和设置样式 通过元素的属性来控制其外观和行为,支持和重要事件交流的事件监听器 详细步骤见:Android 自定义View步骤 ...

  3. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  4. Android 自定义View (五)——实践

    前言: 前面已经介绍了<Android 自定义 view(四)-- onMeasure 方法理解>,那么这次我们就来小实践下吧 任务: 公司现有两个任务需要我完成 (1)监测液化天然气液压 ...

  5. Android 自定义 view(四)—— onMeasure 方法理解

    前言: 前面我们已经学过<Android 自定义 view(三)-- onDraw 方法理解>,那么接下我们还需要继续去理解自定义view里面的onMeasure 方法 推荐文章: htt ...

  6. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  7. Android 自定义view(二) —— attr 使用

    前言: attr 在前一篇文章<Android 自定义view -- attr理解>已经简单的进行了介绍和创建,那么这篇文章就来一步步说说attr的简单使用吧 自定义view简单实现步骤 ...

  8. Android 自定义View

    Android 自定义View流程中的几个方法解析: onFinishInflate():从布局文件.xml加载完组件后回调 onMeasure() :调用该方法负责测量组件大小 onSizeChan ...

  9. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

随机推荐

  1. 通过innobackupex实现对MySQL的完整备份与还原

    备份 新建一个用于存放备份的目录 mkdir /backup 执行以下命令: innobackupex --password=test /backup/ 执行完后你会看到“completed OK!” ...

  2. MySQL_订单类型细分_20161222

    #目前在做一个各城市日订单角度的对比分析,因此需要对订单类型进行一下规整.由于App上产品活动许多,查询了多个表,将订单类型规则进行了统一,优惠券和满减券不能同时使用,创建的这两个表都是以订单ID为k ...

  3. XproerIM-v1.3更新-企业即时通迅

    版权所有 2009-2016 荆门泽优软件有限公司 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/apps/xproerim/index.a ...

  4. --查询nvarchar(max)的表和字段

    --查询nvarchar(max)的表和字段 select 'insert into #tempTabelInfo select '''+d.name+''', '''+a.name+''', max ...

  5. 在Asp.net 4.0 中动态注册HttpModule

    using System; using System.Web; using Microsoft.Web.Infrastructure; namespace MvcApplication1 { publ ...

  6. .net 实现上传文件分割,断点续传上传文件

    一 介绍 断点续传搜索大部分都是下载的断点续传,涉及到HTTP协议1.1的Range和Content-Range头. 来个简单的介绍 所谓断点续传,也就是要从文件已经下载的地方开始继续下载.在以前版本 ...

  7. Java中基本数据类型的对比记忆

    Java中八种基本类型数据情况: 数据类型 所占字节数 所占位数(二进制位数) 可表示范围 默认值 包装类 备注 byte(字节) 1 8 -128 - 127  0  Byte   short(短整 ...

  8. DIOCP之编写第一个应用程序(三)

    Client 设计功能如下: 1.建立与服务器连接 2.请求连接时,加密密码,采用Base64编码 3.定时发送心跳告诉服务器在线(长连接,用于接收推送信息) 4.进行相关的数据处理与交互 第一步:创 ...

  9. JavaIO之File类

    Java-IO之File类 Java-IO之File类 1. File类 1.1. File类说明 1.2. 体验 File 类 1.3. 构造一个 File 类实例: 1.4. 路径: 1.4.1. ...

  10. scala学习之: Flatten a nested list structure

    题目要求: (**) Flatten a nested list structure. Example: scala> flatten(List(List(1, 1), 2, List(3, L ...