1、自定义圆形控件 RoundImageView

  1. package com.ronye.CustomView;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.Bitmap;
  5. import android.graphics.Canvas;
  6. import android.graphics.Paint;
  7. import android.graphics.PorterDuff;
  8. import android.graphics.PorterDuffXfermode;
  9. import android.graphics.Rect;
  10. import android.graphics.drawable.BitmapDrawable;
  11. import android.graphics.drawable.Drawable;
  12. import android.graphics.drawable.NinePatchDrawable;
  13. import android.util.AttributeSet;
  14. import android.widget.ImageView;
  15. import com.ronye.R;
  16.  
  17. /**
  18. * Created by ${zyj} on 2015/8/27.
  19. * 描述: 自定义圆形图片
  20. */
  21. public class RoundImageView extends ImageView {
  22.  
  23. private int mBorderThickness = 0;
  24. private Context mContext;
  25. private int defaultColor = 0xFFFFFFFF;
  26. // 如果只有其中一个有值,则只画一个圆形边框
  27. private int mBorderOutsideColor = 0;
  28. private int mBorderInsideColor = 0;
  29. // 控件默认长、宽
  30. private int defaultWidth = 0;
  31. private int defaultHeight = 0;
  32.  
  33. public RoundImageView(Context context) {
  34. super(context);
  35. mContext = context;
  36. }
  37.  
  38. public RoundImageView(Context context, AttributeSet attrs) {
  39. super(context, attrs);
  40. mContext = context;
  41. setCustomAttributes(attrs);
  42. }
  43.  
  44. public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
  45. super(context, attrs, defStyle);
  46. mContext = context;
  47. setCustomAttributes(attrs);
  48. }
  49.  
  50. private void setCustomAttributes(AttributeSet attrs) {
  51. TypedArray a = mContext.obtainStyledAttributes(attrs,R.styleable.roundedimageview);
  52. mBorderThickness = a.getDimensionPixelSize(R.styleable.roundedimageview_border_thickness, 0);
  53. mBorderOutsideColor = a.getColor(R.styleable.roundedimageview_border_outside_color,defaultColor);
  54. mBorderInsideColor = a.getColor(R.styleable.roundedimageview_border_inside_color, defaultColor);
  55. }
  56.  
  57. @Override
  58. protected void onDraw(Canvas canvas) {
  59. Drawable drawable = getDrawable() ;
  60. if (drawable == null) {
  61. return;
  62. }
  63. if (getWidth() == 0 || getHeight() == 0) {
  64. return;
  65. }
  66. this.measure(0, 0);
  67. if (drawable.getClass() == NinePatchDrawable.class)
  68. return;
  69. Bitmap b = ((BitmapDrawable) drawable).getBitmap();
  70. Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
  71. if (defaultWidth == 0) {
  72. defaultWidth = getWidth();
  73. }
  74. if (defaultHeight == 0) {
  75. defaultHeight = getHeight();
  76. }
  77. int radius = 0;
  78. if (mBorderInsideColor != defaultColor && mBorderOutsideColor != defaultColor) {// 定义画两个边框,分别为外圆边框和内圆边框
  79. radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - 2 * mBorderThickness;
  80. // 画内圆
  81. drawCircleBorder(canvas, radius + mBorderThickness / 2,mBorderInsideColor);
  82. // 画外圆
  83. drawCircleBorder(canvas, radius + mBorderThickness + mBorderThickness / 2, mBorderOutsideColor);
  84. } else if (mBorderInsideColor != defaultColor && mBorderOutsideColor == defaultColor) {// 定义画一个边框
  85. radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - mBorderThickness;
  86. drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderInsideColor);
  87. } else if (mBorderInsideColor == defaultColor && mBorderOutsideColor != defaultColor) {// 定义画一个边框
  88. radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2 - mBorderThickness;
  89. drawCircleBorder(canvas, radius + mBorderThickness / 2, mBorderOutsideColor);
  90. } else {// 没有边框
  91. radius = (defaultWidth < defaultHeight ? defaultWidth : defaultHeight) / 2;
  92. }
  93. Bitmap roundBitmap = getCroppedRoundBitmap(bitmap, radius);
  94. canvas.drawBitmap(roundBitmap, defaultWidth / 2 - radius, defaultHeight / 2 - radius, null);
  95. }
  96.  
  97. /**
  98. * 获取裁剪后的圆形图片
  99. * @param bmp
  100. * @param radius 半径
  101. * @return
  102. */
  103. public Bitmap getCroppedRoundBitmap(Bitmap bmp, int radius) {
  104. Bitmap scaledSrcBmp;
  105. int diameter = radius * 2;
  106. // 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图片
  107. int bmpWidth = bmp.getWidth();
  108. int bmpHeight = bmp.getHeight();
  109. int squareWidth = 0, squareHeight = 0;
  110. int x = 0, y = 0;
  111. Bitmap squareBitmap;
  112. if (bmpHeight > bmpWidth) {// 高大于宽
  113. squareWidth = squareHeight = bmpWidth;
  114. x = 0;
  115. y = (bmpHeight - bmpWidth) / 2;
  116. // 截取正方形图片
  117. squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
  118. } else if (bmpHeight < bmpWidth) {// 宽大于高
  119. squareWidth = squareHeight = bmpHeight;
  120. x = (bmpWidth - bmpHeight) / 2;
  121. y = 0;
  122. squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth,squareHeight);
  123. } else {
  124. squareBitmap = bmp;
  125. }
  126. if (squareBitmap.getWidth() != diameter || squareBitmap.getHeight() != diameter) {
  127. scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap, diameter,diameter, true);
  128. } else {
  129. scaledSrcBmp = squareBitmap;
  130. }
  131. Bitmap output = Bitmap.createBitmap(scaledSrcBmp.getWidth(),
  132. scaledSrcBmp.getHeight(),
  133. Bitmap.Config.ARGB_8888);
  134. Canvas canvas = new Canvas(output);
  135.  
  136. Paint paint = new Paint();
  137. Rect rect = new Rect(0, 0, scaledSrcBmp.getWidth(),scaledSrcBmp.getHeight());
  138.  
  139. paint.setAntiAlias(true);
  140. paint.setFilterBitmap(true);
  141. paint.setDither(true);
  142. canvas.drawARGB(0, 0, 0, 0);
  143. canvas.drawCircle(scaledSrcBmp.getWidth() / 2,
  144. scaledSrcBmp.getHeight() / 2,
  145. scaledSrcBmp.getWidth() / 2,
  146. paint);
  147. paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  148. canvas.drawBitmap(scaledSrcBmp, rect, rect, paint);
  149. bmp = null;
  150. squareBitmap = null;
  151. scaledSrcBmp = null;
  152. return output;
  153. }
  154.  
  155. /**
  156. * 边缘画圆
  157. */
  158. private void drawCircleBorder(Canvas canvas, int radius, int color) {
  159. Paint paint = new Paint();
  160. /* 去锯齿 */
  161. paint.setAntiAlias(true);
  162. paint.setFilterBitmap(true);
  163. paint.setDither(true);
  164. paint.setColor(color);
  165. /* 设置paint的 style 为STROKE:空心 */
  166. paint.setStyle(Paint.Style.STROKE);
  167. /* 设置paint的外框宽度 */
  168. paint.setStrokeWidth(mBorderThickness);
  169. canvas.drawCircle(defaultWidth / 2, defaultHeight / 2, radius, paint);
  170. }
  171. }

2、定义自己的属性配置文件:attr.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <declare-styleable name="roundedimageview">
  4. <attr name="border_thickness" format="dimension" />
  5. <attr name="border_inside_color" format="color" />
  6. <attr name="border_outside_color" format="color"></attr>
  7. </declare-styleable>
  8. </resources>

3、在xml配置中使用控件:activity_main.xml

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. xmlns:imagecontrol="http://schemas.android.com/apk/res-auto"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:orientation="horizontal"
  7. >
  8.  
  9. <!-- 没有指定圆形ImageView属性时,默认没有外边圆颜色 -->
  10. <!-- 需要将图片资源自定为src ,或在程序中setImageResource(res) 不能设置background为图片,这样不能达到圆形效果-->
  11. <com.dxd.roundimageview.RoundImageView
  12. android:layout_width="100dp"
  13. android:layout_height="100dp"
  14. android:src="@drawable/img"
  15. />
  16. <!-- border_outside_color 外部圆圈的颜色 -->
  17. <!-- border_inside_color 内部部圆圈的颜色 -->
  18. <!-- border_thickness 外圆和内圆的宽度 -->
  19. <com.dxd.roundimageview.RoundImageView
  20. android:layout_width="100dp"
  21. android:layout_height="100dp"
  22. android:src="@drawable/img"
  23. imagecontrol:border_inside_color="#bc0978"
  24. imagecontrol:border_outside_color="#ba3456"
  25. imagecontrol:border_thickness="1dp"
  26. />
  27. </LinearLayout>

4、运行结果

   

自定义圆形控件 RoundImageView的更多相关文章

  1. 自定义圆形控件RoundImageView并认识一下attr.xml

    今天我们来讲一下有关自定义控件的问题,今天讲的这篇是从布局自定义开始的,难度不大,一看就明白,估计有的同学或者开发者看了说,这种方式多此一举,但是小编我不这么认为,多一种解决方式,就多一种举一反三的学 ...

  2. 自定义圆形控件RoundImageView并认识一下attr

    昨天我们学习了自定义带图片和文字的ImageTextButton,非常简单,我承诺给大家要讲一下用自定义属性的方式学习真正的实现自定义控件,在布局文件中使用属性的方式就需要用到attr.xml这个文件 ...

  3. CircleImageView自定义圆形控件的使用

    1.自定义圆形控件github地址: https://github.com/hdodenhof/CircleImageView 主要的类: package de.hdodenhof.circleima ...

  4. Android开发(二)——自定义圆形控件的使用CircleImageView

    CircleImageView,a fast circular ImageView perfect for profile images. 主要的类CircleImageView: package d ...

  5. 【Android开源】CircleImageView自定义圆形控件的使用

    github地址:https://github.com/hdodenhof/CircleImageView package de.hdodenhof.circleimageview; import e ...

  6. 安卓自定义组合控件--toolbar

    最近在学习安卓APP的开发,用到了toolbar这个控件, 最开始使用时include layout这种方法,不过感觉封装性不好,就又改成了自定义组合控件的方式. 使用的工具为android stud ...

  7. Android自定义控件之自定义组合控件

    前言: 前两篇介绍了自定义控件的基础原理Android自定义控件之基本原理(一).自定义属性Android自定义控件之自定义属性(二).今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发 ...

  8. asp.net webform 自定义分页控件

    做web开发一直用到分页控件,自己也动手实现了个,使用用户自定义控件. 翻页后数据加载使用委托,将具体实现放在在使用分页控件的页面进行注册. 有图有真相,给个直观的认识: 自定义分页控件前台代码: & ...

  9. arcgis api for js共享干货系列之二自定义Navigation控件样式风格

    arcgis api for js默认的Navigation控件样式风格如下图: 这样的风格不能说不好,各有各的爱好,审美观,这里也不是重点,这里的重点是如何自定义一套自己喜欢的样式风格呢:自己自定义 ...

随机推荐

  1. 11款扁平化设计的 Twitter Bootstrap 主题和模板

    扁平化设计和 Bootstrap 框架是2013年网页设计领域的两大设计潮流.把这两者集合起来不是件容易的事情,使用下面这些主题和模板将节省我们的开发时间,因为我们可以修改已有的基础代码,而不是从零开 ...

  2. Django--models多对多

    多对多--ManyToMany 应用场景 在某表中创建一行数据时,有一个可以多选的下拉框(一对一是单选框)例如:创建用户信息,需要为用户指定多个爱好 创建表 两种方法,一个是利用Django自动为多对 ...

  3. ECharts+BaiduMap+HT for Web网络拓扑图应用

    前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...

  4. HTML语义化:HTML5新标签——template

    一.前言 当我们使用String-base的模板引擎(如Handlebars.js等)时,要么就通过外部文件存放模板文本,需要时再通过XHR或script标签加载进来:要么通过<script t ...

  5. Spark RDD到底是个什么东西

    前言 用Spark有一段时间了,但是感觉还是停留在表面,对于Spark的RDD的理解还是停留在概念上,即只知道它是个弹性分布式数据集,其他的一概不知 有点略显惭愧.下面记录下我对RDD的新的理解. 官 ...

  6. C语言学习015:联合(union)与枚举(enum)

    联合 联合和结构的区别是,结构会为每个字段申请一片内存空间,而联合只是申请了一片内存空间然后所有字段都会保存到这片空间中,这片空间的大小由字段中最长的决定,下面我们就开始定义一个联合 //联合的定义 ...

  7. 【WebService】WebService的创建和使用——文件名称生成器

    简介 之前做过一个文件名称生成器,通过Webservice读取XML文件并将其通过Json传到客户端中的combobx,用户通过combobox选择要生成文件的名称模板,点击生成则会产生一个文件名称并 ...

  8. C#获取执行存储过程的" 返回值"代码

    以下是C#代码: /// <summary> /// 执行存储过程,返回" 返回值" /// </summary> /// <param name=& ...

  9. 注意:DateTimePicker.Text不靠谱

    这鸟属性把我害苦过,特此敬告一下大家.具体表现在: 获取时:在DateTimePicker.ValueChanged事件中,获取到的Text有可能是string.Empty!!!,特别当ValueCh ...

  10. C#编程总结(九)字符编码

    C#编程总结(九)字符编码 相信大家一定遇到过乱码的问题,为什么会乱码呢?输出的数据怎么就跟输入的不一样呢? 最近在总结加密问题,也遇到了同样的困扰.所以今天来集中解决这个问题. 什么是字符? 字符是 ...