1.定义自己的圆形控制github住址:https://github.com/hdodenhof/CircleImageView

基本的类:

  1. package de.hdodenhof.circleimageview;
  2. import edu.njupt.zhb.main.R;
  3. import android.content.Context;
  4. import android.content.res.TypedArray;
  5. import android.graphics.Bitmap;
  6. import android.graphics.BitmapShader;
  7. import android.graphics.Canvas;
  8. import android.graphics.Color;
  9. import android.graphics.Matrix;
  10. import android.graphics.Paint;
  11. import android.graphics.RectF;
  12. import android.graphics.Shader;
  13. import android.graphics.drawable.BitmapDrawable;
  14. import android.graphics.drawable.ColorDrawable;
  15. import android.graphics.drawable.Drawable;
  16. import android.util.AttributeSet;
  17. import android.widget.ImageView;
  18.  
  19. public class CircleImageView extends ImageView {
  20.  
  21. private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
  22.  
  23. private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
  24. private static final int COLORDRAWABLE_DIMENSION = 1;
  25.  
  26. private static final int DEFAULT_BORDER_WIDTH = 0;
  27. private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
  28.  
  29. private final RectF mDrawableRect = new RectF();
  30. private final RectF mBorderRect = new RectF();
  31.  
  32. private final Matrix mShaderMatrix = new Matrix();
  33. private final Paint mBitmapPaint = new Paint();
  34. private final Paint mBorderPaint = new Paint();
  35.  
  36. private int mBorderColor = DEFAULT_BORDER_COLOR;
  37. private int mBorderWidth = DEFAULT_BORDER_WIDTH;
  38.  
  39. private Bitmap mBitmap;
  40. private BitmapShader mBitmapShader;
  41. private int mBitmapWidth;
  42. private int mBitmapHeight;
  43.  
  44. private float mDrawableRadius;
  45. private float mBorderRadius;
  46.  
  47. private boolean mReady;
  48. private boolean mSetupPending;
  49.  
  50. public CircleImageView(Context context) {
  51. super(context);
  52. }
  53.  
  54. public CircleImageView(Context context, AttributeSet attrs) {
  55. this(context, attrs, 0);
  56. }
  57.  
  58. public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
  59. super(context, attrs, defStyle);
  60. super.setScaleType(SCALE_TYPE);
  61.  
  62. TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
  63.  
  64. mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
  65. mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
  66.  
  67. a.recycle();
  68.  
  69. mReady = true;
  70.  
  71. if (mSetupPending) {
  72. setup();
  73. mSetupPending = false;
  74. }
  75. }
  76.  
  77. @Override
  78. public ScaleType getScaleType() {
  79. return SCALE_TYPE;
  80. }
  81.  
  82. @Override
  83. public void setScaleType(ScaleType scaleType) {
  84. if (scaleType != SCALE_TYPE) {
  85. throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
  86. }
  87. }
  88.  
  89. @Override
  90. protected void onDraw(Canvas canvas) {
  91. if (getDrawable() == null) {
  92. return;
  93. }
  94.  
  95. canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);
  96. canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);
  97. }
  98.  
  99. @Override
  100. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  101. super.onSizeChanged(w, h, oldw, oldh);
  102. setup();
  103. }
  104.  
  105. public int getBorderColor() {
  106. return mBorderColor;
  107. }
  108.  
  109. public void setBorderColor(int borderColor) {
  110. if (borderColor == mBorderColor) {
  111. return;
  112. }
  113.  
  114. mBorderColor = borderColor;
  115. mBorderPaint.setColor(mBorderColor);
  116. invalidate();
  117. }
  118.  
  119. public int getBorderWidth() {
  120. return mBorderWidth;
  121. }
  122.  
  123. public void setBorderWidth(int borderWidth) {
  124. if (borderWidth == mBorderWidth) {
  125. return;
  126. }
  127.  
  128. mBorderWidth = borderWidth;
  129. setup();
  130. }
  131.  
  132. @Override
  133. public void setImageBitmap(Bitmap bm) {
  134. super.setImageBitmap(bm);
  135. mBitmap = bm;
  136. setup();
  137. }
  138.  
  139. @Override
  140. public void setImageDrawable(Drawable drawable) {
  141. super.setImageDrawable(drawable);
  142. mBitmap = getBitmapFromDrawable(drawable);
  143. setup();
  144. }
  145.  
  146. @Override
  147. public void setImageResource(int resId) {
  148. super.setImageResource(resId);
  149. mBitmap = getBitmapFromDrawable(getDrawable());
  150. setup();
  151. }
  152.  
  153. private Bitmap getBitmapFromDrawable(Drawable drawable) {
  154. if (drawable == null) {
  155. return null;
  156. }
  157.  
  158. if (drawable instanceof BitmapDrawable) {
  159. return ((BitmapDrawable) drawable).getBitmap();
  160. }
  161.  
  162. try {
  163. Bitmap bitmap;
  164.  
  165. if (drawable instanceof ColorDrawable) {
  166. bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
  167. } else {
  168. bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
  169. }
  170.  
  171. Canvas canvas = new Canvas(bitmap);
  172. drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
  173. drawable.draw(canvas);
  174. return bitmap;
  175. } catch (OutOfMemoryError e) {
  176. return null;
  177. }
  178. }
  179.  
  180. private void setup() {
  181. if (!mReady) {
  182. mSetupPending = true;
  183. return;
  184. }
  185.  
  186. if (mBitmap == null) {
  187. return;
  188. }
  189.  
  190. mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  191.  
  192. mBitmapPaint.setAntiAlias(true);
  193. mBitmapPaint.setShader(mBitmapShader);
  194.  
  195. mBorderPaint.setStyle(Paint.Style.STROKE);
  196. mBorderPaint.setAntiAlias(true);
  197. mBorderPaint.setColor(mBorderColor);
  198. mBorderPaint.setStrokeWidth(mBorderWidth);
  199.  
  200. mBitmapHeight = mBitmap.getHeight();
  201. mBitmapWidth = mBitmap.getWidth();
  202.  
  203. mBorderRect.set(0, 0, getWidth(), getHeight());
  204. mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);
  205.  
  206. mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);
  207. mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
  208.  
  209. updateShaderMatrix();
  210. invalidate();
  211. }
  212.  
  213. private void updateShaderMatrix() {
  214. float scale;
  215. float dx = 0;
  216. float dy = 0;
  217.  
  218. mShaderMatrix.set(null);
  219.  
  220. if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
  221. scale = mDrawableRect.height() / (float) mBitmapHeight;
  222. dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
  223. } else {
  224. scale = mDrawableRect.width() / (float) mBitmapWidth;
  225. dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
  226. }
  227.  
  228. mShaderMatrix.setScale(scale, scale);
  229. mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) + mBorderWidth);
  230.  
  231. mBitmapShader.setLocalMatrix(mShaderMatrix);
  232. }
  233.  
  234. }

自己定义的属性:res/values/attrs.xml

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

使用时的布局文件:

  1. <?
  2.  
  3. xml version="1.0" encoding="utf-8"?
  4.  
  5. >
  6. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  7. xmlns:app="http://schemas.android.com/apk/res-auto"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:orientation="vertical" >
  11. <RelativeLayout
  12. android:layout_width="match_parent"
  13. android:layout_height="0dp"
  14. android:layout_weight="1"
  15. android:padding="@dimen/base_padding"
  16. android:background="@color/light">
  17.  
  18. <de.hdodenhof.circleimageview.CircleImageView
  19. android:layout_width="160dp"
  20. android:layout_height="160dp"
  21. android:layout_centerInParent="true"
  22. android:src="@drawable/demo"
  23. app:border_width="2dp"
  24. app:border_color="@color/dark" />
  25.  
  26. </RelativeLayout>
  27.  
  28. <RelativeLayout
  29. android:layout_width="match_parent"
  30. android:layout_height="0dp"
  31. android:layout_weight="1"
  32. android:padding="@dimen/base_padding"
  33. android:background="@color/dark">
  34.  
  35. <de.hdodenhof.circleimageview.CircleImageView
  36. android:layout_width="160dp"
  37. android:layout_height="160dp"
  38. android:layout_centerInParent="true"
  39. android:src="@drawable/lena"
  40. app:border_width="2dp"
  41. app:border_color="@color/light" />
  42.  
  43. </RelativeLayout>
  44.  
  45. </LinearLayout>

效果:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbnVwdDEyMzQ1Njc4OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />

Demo下载:http://download.csdn.net/detail/nuptboyzhb/7284553

注意:有些开发人员可能也发现了。假设我们须要一个圆形的ImageButton的话,事实上,我们没有必要自己写。假设ImageButton的图标是固定不变的。我们全然能够让设计师给我设计一个圆形的图片,然后直接设置再ImageButton上就能够了。

可是,请注意,我们这里的圆形ImageView是自己定义控件,也即是:不管你设置的图片是什么样的。显示出来的就是圆的。比方:易信中用户头像的设置,不管用户拍什么的照片,显示出来都是一个圆的。

拓展阅读

另一个更加强大的RoundedImageView,还支持圆角。椭圆等等。

https://github.com/vinc3m1/RoundedImageView

版权声明:本文博主原创文章。博客,未经同意不得转载。

android开源系列:CircleImageView采用圆形控制它们的定义的更多相关文章

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

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

  2. 【Android开源项目分析】自定义圆形头像CircleImageView的使用和源码分析

    原文地址: http://blog.csdn.net/zhoubin1992/article/details/47258639 效果

  3. Android开源系列:仿网易Tab分类排序控件实现

    前言 产品:网易新闻那个Tab排序好帅. 开发:哦~ 然后这个东东在几天后就出现了..... (PS:差不多一年没回来写博客了~~~~(>_<)~~~~,顺便把名字从 enjoy风铃 修改 ...

  4. android开源系列之——xUtils 开源库

    http://blog.csdn.net/lijunhuayc/article/details/40585607

  5. Android开发系列(十八):自己定义控件样式在drawable目录下的XML实现

    在Android开发的过程中,我们常常须要对控件的样式做一下改变,能够通过用添加背景图片的方式进行改变,可是背景图片放多了肯定会使得APK文件变的非常大. 我们能够用自己定义属性shape来实现. s ...

  6. Android 开源简单控件

    Android开源系列分类 查看 CircleImageView 自定义圆形控件的使用 添加依赖 ‘de.hdodenhof:circleimageview:2.1.0' 作用:无论你设置的图片是什么 ...

  7. Android自定义控件系列之应用篇——圆形进度条

    一.概述 在上一篇博文中,我们给大家介绍了Android自定义控件系列的基础篇.链接:http://www.cnblogs.com/jerehedu/p/4360066.html 这一篇博文中,我们将 ...

  8. 2015-2016最火的Android开源项目--github开源项目集锦(不看你就out了)

    标签: Android开发开源项目最火Android项目github 2015-2016最火的Android开源项目 本文整理与集结了近期github上使用最广泛最火热与最流行的开源项目,想要充电与提 ...

  9. Android开源项目分类汇总

    目前包括: Android开源项目第一篇——个性化控件(View)篇   包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView. ...

随机推荐

  1. 【Android笔记】MediaPlayer基本用法

    Android MediaPlayer基本使用方式 使用MediaPlayer播放音频或者视频的最简单样例: JAVA代码部分: public class MediaPlayerStudy exten ...

  2. ehcache.xml设置(转)

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLoc ...

  3. mtk硬件项目开始关闭蓝牙功能:mtk 硬件ScanCode和keycode应用演示示例

    项目要求:该项目因为没有使用android5.0,导致启动bluetooth的蓝牙audio slave功能必须使用第三方模组,该第三方模组,启动是通过android主板通过GPIO控制.UI界面是通 ...

  4. 第九讲:HTML5该canvas推箱子原型实现

    <html> <head> <title>动</title> <script src="../js/jscex.jscexRequire ...

  5. 数据结构 - 双链表(C++)

    // ------DoublyLinkedList.h------ template <class T> class DNode { private: // 指向左.右结点的指针 DNod ...

  6. 注意事项: Solr设备 Hello World

    试用 Solr-4.10.2 一 shards, 这两款机器 一是垃圾 rm -r example/solr/collection1/data/* 启动一个 node cd example java ...

  7. Android-管理Activity生命周期 -暂停和恢复一个Activity

    在正常的使用app时,前台的activity有时候会被可见的组件阻塞导致activity暂停.比如,当打开一个半透明的activity(就像打开了一个对话框),之前的activity就会暂停.只要ac ...

  8. Spark里边:Worker源代码分析和架构

    首先由Spark图表理解Worker于Spark中的作用和地位: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYW56aHNvZnQ=/font/5a6L ...

  9. Atitit. 拉开拉链zip文件 最佳实践实施 java c# .net php

    Atitit. 拉开拉链zip文件 的实现最佳实践 java c# .net php 1. Jdk zip 跟apache ant zip 1 2. Apache Ant包进行ZIP文件压缩,upzi ...

  10. 【转】ubuntu终端方向键不能用(主机名不显示)问题的解决

    sudo gedit /etc/passwd 在/etc/passwd中修改该用户对应的shell:/bin/sh改为/bin/bash即可解决该问题 来自:http://blog.csdn.net/ ...