Android自定义View之CircleView

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

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

前言

大家好,我是Cavalier,这次和大家分享一下《Android自定义View之CircleView》,不废话,下面上效果图。

分析

需求

  1. 1:随机换颜色的一个view
  2. 2:可以设置文字

动手

Setup1:继承自View,重写三个构造函数

  1. public class CircleView extends View {
  2. public CircleView(Context context) {
  3. this(context,null);
  4. }
  5. public CircleView(Context context, AttributeSet attrs) {
  6. this(context, attrs,0);
  7. }
  8. public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
  9. super(context, attrs, defStyleAttr);
  10. }
  11. }

上面代码中重写了三个构造函数,其中第一个是用于直接new对象,第二个是从xml创建时没有指定style时调用,第三个是指定了style时调用,通过this可以直接指向第三个构造参数,所有初始化可以直接写在第三个构造参数中

Setup2:声明所需的变量

  1. private Paint mTextPain; //初始化画笔
  2. private String mText = ""; //初始化文字
  3. private int radius; //当前View的半径
  4. ...
  5. public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
  6. super(context, attrs, defStyleAttr);
  7. configPaint();
  8. }
  9. private void configPaint() {
  10. mTextPain = new Paint();
  11. mTextPain.setColor(Color.WHITE); //设置画笔颜色为白色
  12. mTextPain.setAntiAlias(true); //开启抗锯齿,平滑文字和圆弧的边缘
  13. mTextPain.setTextAlign(Paint.Align.CENTER); //设置文本位于相对于原点的中间
  14. }

上面代码在第三个构造函数调用了configPaint函数

Setup3:重新onDraw函数

  1. @Override
  2. protected void onDraw(Canvas canvas) {
  3. super.onDraw(canvas);
  4. int width = getWidth() / 2; //获取宽度一半
  5. int height = getHeight() / 2; //获取高度一半
  6. radius = Math.min(width, height); //设置半径为宽或者高的最小值
  7. //paint bg
  8. mTextPain.setColor(Color.parseColor(getRandomColor())); //设置画笔颜色为随机颜色
  9. canvas.drawCircle(width, height, radius, mTextPain); //利用canvas画一个圆
  10. //paint font
  11. mTextPain.setColor(Color.WHITE); //设置画笔白颜色
  12. mTextPain.setTextSize(dp2px(16)); //设置字体大小为16dp
  13. Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //获取字体测量对象
  14. canvas.drawText(mText, 0, mText.length(), radius //利用canvas画上字
  15. , radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain);
  16. }

上面代码中先获取到当前view的宽和高,取其中最小值作为背景的半径,设置了随机颜色做背景,且利用FontMetrics获取了文字的绘制位置

Setup4:添加两个辅助函数,dp2px和getRandomColor

  1. /**
  2. * 给View设置文字
  3. * @param str
  4. */
  5. public void setText(String str) {
  6. if(!TextUtils.isEmpty(str)){
  7. if(str.length()>1){
  8. mText = str.substring(0,1);
  9. }else {
  10. mText = str;
  11. }
  12. }else {
  13. mText = "";
  14. }
  15. invalidate();
  16. }

当然,我们需要将设置文字暴露给使用者,这里利用了invalidate让CircleView重新绘制一遍,目的是更改内中的文字

Setup5:添加两个辅助函数,dp2px和getRandomColor

  1. /**
  2. * dp转px
  3. *
  4. * @param dp
  5. * @return
  6. */
  7. private int dp2px(int dp) {
  8. // px = dp * (dpi / 160)
  9. DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
  10. int dpi = metrics.densityDpi;
  11. return (int) (dp * (dpi / 160f) + 0.5f);
  12. }
  13. /**
  14. * 获取随机颜色
  15. *
  16. * @return
  17. */
  18. private String getRandomColor() {
  19. List<String> colorList = new ArrayList<String>();
  20. colorList.add("#303F9F");
  21. colorList.add("#FF4081");
  22. colorList.add("#59dbe0");
  23. colorList.add("#f57f68");
  24. colorList.add("#f8b552");
  25. colorList.add("#990099");
  26. colorList.add("#90a4ae");
  27. colorList.add("#7baaf7");
  28. colorList.add("#4dd0e1");
  29. colorList.add("#4db6ac");
  30. colorList.add("#aed581");
  31. colorList.add("#fdd835");
  32. colorList.add("#f2a600");
  33. colorList.add("#ff8a65");
  34. colorList.add("#f48fb1");
  35. colorList.add("#7986cb");
  36. colorList.add("#DEB887");
  37. colorList.add("#FF69B4");
  38. return colorList.get((int) (Math.random() * colorList.size()));
  39. }

补充了这两个辅助函数后,代码已经完成了

How to use?

在XML中使用

  1. ...
  2. <com.ram.testdemo.view.CircleView
  3. android:id="@+id/cv"
  4. android:layout_width="50dp"
  5. android:layout_height="50dp"/>
  6. ...

这里注意调用时是使用你自己的Class文件全路径。

在java中使用

  1. CircleView mCircleView = (CircleView) findViewById(R.id.cv);
  2. mCircleView.setText("哈哈");

Souce Code

  1. public class CircleView extends View {
  2. private Paint mTextPain; //初始化画笔
  3. private String mText = ""; //初始化文字
  4. private int radius; //当前View的半径
  5. public CircleView(Context context) {
  6. this(context, null);
  7. }
  8. public CircleView(Context context, AttributeSet attrs) {
  9. this(context, attrs, 0);
  10. }
  11. public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
  12. super(context, attrs, defStyleAttr);
  13. configPaint();
  14. }
  15. private void configPaint() {
  16. mTextPain = new Paint();
  17. mTextPain.setColor(Color.WHITE); //设置画笔颜色为白色
  18. mTextPain.setAntiAlias(true); //开启抗锯齿,平滑文字和圆弧的边缘
  19. mTextPain.setTextAlign(Paint.Align.CENTER); //设置文本位于相对于原点的中间
  20. }
  21. @Override
  22. protected void onDraw(Canvas canvas) {
  23. super.onDraw(canvas);
  24. int width = getWidth() / 2; //获取宽度一半
  25. int height = getHeight() / 2; //获取高度一半
  26. radius = Math.min(width, height); //设置半径为宽或者高的最小值
  27. //paint bg
  28. mTextPain.setColor(Color.parseColor(getRandomColor())); //设置画笔颜色为随机颜色
  29. canvas.drawCircle(width, height, radius, mTextPain); //利用canvas画一个圆
  30. //paint font
  31. mTextPain.setColor(Color.WHITE); //设置画笔白颜色
  32. mTextPain.setTextSize(dp2px(16)); //设置字体大小为16dp
  33. Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //获取字体测量对象
  34. canvas.drawText(mText, 0, mText.length(), radius //利用canvas画上字
  35. , radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain);
  36. }
  37. /**
  38. * 给View设置文字
  39. * @param str
  40. */
  41. public void setText(String str) {
  42. if(!TextUtils.isEmpty(str)){
  43. if(str.length()>1){
  44. mText = str.substring(0,1);
  45. }else {
  46. mText = str;
  47. }
  48. }else {
  49. mText = "";
  50. }
  51. invalidate();
  52. }
  53. /**
  54. * dp转px
  55. *
  56. * @param dp
  57. * @return
  58. */
  59. public int dp2px(int dp) {
  60. // px = dp * (dpi / 160)
  61. DisplayMetrics metrics = getContext().getResources().getDisplayMetrics();
  62. int dpi = metrics.densityDpi;
  63. return (int) (dp * (dpi / 160f) + 0.5f);
  64. }
  65. /**
  66. * 获取随机颜色
  67. *
  68. * @return
  69. */
  70. private String getRandomColor() {
  71. List<String> colorList = new ArrayList<String>();
  72. colorList.add("#303F9F");
  73. colorList.add("#FF4081");
  74. colorList.add("#59dbe0");
  75. colorList.add("#f57f68");
  76. colorList.add("#f8b552");
  77. colorList.add("#990099");
  78. colorList.add("#90a4ae");
  79. colorList.add("#7baaf7");
  80. colorList.add("#4dd0e1");
  81. colorList.add("#4db6ac");
  82. colorList.add("#aed581");
  83. colorList.add("#fdd835");
  84. colorList.add("#f2a600");
  85. colorList.add("#ff8a65");
  86. colorList.add("#f48fb1");
  87. colorList.add("#7986cb");
  88. colorList.add("#DEB887");
  89. colorList.add("#FF69B4");
  90. return colorList.get((int) (Math.random() * colorList.size()));
  91. }
  92. }

结尾

本篇中,我们掌握了自定义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. 微信官方demo(php)

    <?php /** * wechat php test */ //define your token define("TOKEN", "weixin"); ...

  2. 把内容生成txt文件

    StringBuilder MailLog = new StringBuilder();            string logPath = txtFile + str + DateTime.No ...

  3. php获取时间问题,用默认配置读到本地时间。。。。。

    用date获取到时间有8小时时差 因为php用date获取到的是格林威治时区的时间,而大陆时间和格林威治时间有8个小时时差,所以.... 修改:网上有各种修改方式: 比如:在程序中添加时间的初始化的语 ...

  4. javascript-binarySearch

    前提: 数组已排序,且为正整数数组. function brnarySearch(arg, arr) { var right = arr.length - 1; var left = 0; while ...

  5. PHP面向对象_重载新的方法(parent::)

    在学习PHP 这种语言中你会发现, PHP中的方法是不能重载的, 所谓的方法重载就是定义相同的方法名,通过“参数的个数“不同或“参数的类型“不 同,来访问我们的相同方法名的不同方法.但是因为PHP是弱 ...

  6. VC++ 截屏代码,并保存为想要的格式(BMP,JPG,PNG,GIF等格式)

    void CCaptionScreenDlg::Screen(char* filename) { HDC hdcSrc = ::GetDC(NULL); int nBitPerPixel = GetD ...

  7. kindeditor多图片上传找不到action原来是private File upload成员变量惹得祸

    kindeditor多图片上传找不到action原来是private File upload成员变量惹得祸

  8. spring-mybatis jar下载地址

    http://central.maven.org/maven2/org/mybatis/mybatis-spring/1.3.0/

  9. ViewPager+PagerTabStrip实现页面的切换

    页面切换效果图 首先创建布局: 代码: <?xml version="1.0" encoding="utf-8"?><LinearLayout ...

  10. Linux Daemon 类程序

    1.后台daemon程序(精灵程序) 在Linux中专门提供了一个函数来完成这个daemon化的过程,这个函数的原型如下 int daemon (int __nochdir, int __noclos ...