github上有个开源项目CircleImageView,可以简单的实现一个圆形的ImageView,就像qq头像那样。

NetworkImageView是volley中的一个组件,可以方便的加载网络图片并显示出来。

CircleImageView不能自动加载网络图片,NetworkImageView不能设置成圆形,但是目前项目中就是需要这样做,这要怎么办呢?

于是去看了看两者的源码,都是继承ImagevView的,并且CircleImageView的实现要比较简单一些。于是就有了一个思路,自己把CircleImageView重写一遍,将CircleImageView的父类由ImageView改为NetworkImageView,这样的话就可以结合两者的优点。

代码如下,请先自己引入Volley依赖。

  1. package com.mmia.widget;
  2.  
  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.ColorFilter;
  10. import android.graphics.Matrix;
  11. import android.graphics.Paint;
  12. import android.graphics.RadialGradient;
  13. import android.graphics.RectF;
  14. import android.graphics.Shader;
  15. import android.graphics.drawable.BitmapDrawable;
  16. import android.graphics.drawable.ColorDrawable;
  17. import android.graphics.drawable.Drawable;
  18. import android.graphics.drawable.ShapeDrawable;
  19. import android.graphics.drawable.shapes.OvalShape;
  20. import android.net.Uri;
  21. import android.support.annotation.ColorInt;
  22. import android.support.annotation.ColorRes;
  23. import android.support.annotation.DrawableRes;
  24. import android.support.v4.view.ViewCompat;
  25. import android.util.AttributeSet;
  26. import android.view.animation.Animation;
  27.  
  28. import com.android.volley.toolbox.NetworkImageView;
  29. import com.mmia.client.R;
  30.  
  31. /**
  32. * csonezp
  33. * 圆形的NetworkImageview
  34. * 代码来自开源项目CircleImageView
  35. */
  36. public class CircleNetworkImage extends NetworkImageView {
  37.  
  38. private static final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
  39.  
  40. private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
  41. private static final int COLORDRAWABLE_DIMENSION = 2;
  42.  
  43. private static final int DEFAULT_BORDER_WIDTH = 0;
  44. private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
  45. private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
  46. private static final boolean DEFAULT_BORDER_OVERLAY = false;
  47.  
  48. private final RectF mDrawableRect = new RectF();
  49. private final RectF mBorderRect = new RectF();
  50.  
  51. private final Matrix mShaderMatrix = new Matrix();
  52. private final Paint mBitmapPaint = new Paint();
  53. private final Paint mBorderPaint = new Paint();
  54. private final Paint mFillPaint = new Paint();
  55.  
  56. private int mBorderColor = DEFAULT_BORDER_COLOR;
  57. private int mBorderWidth = DEFAULT_BORDER_WIDTH;
  58. private int mFillColor = DEFAULT_FILL_COLOR;
  59.  
  60. private Bitmap mBitmap;
  61. private BitmapShader mBitmapShader;
  62. private int mBitmapWidth;
  63. private int mBitmapHeight;
  64.  
  65. private float mDrawableRadius;
  66. private float mBorderRadius;
  67.  
  68. private ColorFilter mColorFilter;
  69.  
  70. private boolean mReady;
  71. private boolean mSetupPending;
  72. private boolean mBorderOverlay;
  73.  
  74. public CircleNetworkImage(Context context) {
  75. super(context);
  76.  
  77. init();
  78. }
  79.  
  80. public CircleNetworkImage(Context context, AttributeSet attrs) {
  81. this(context, attrs, 0);
  82. }
  83.  
  84. public CircleNetworkImage(Context context, AttributeSet attrs, int defStyle) {
  85. super(context, attrs, defStyle);
  86.  
  87. TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
  88.  
  89. mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
  90. mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
  91. mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
  92. mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
  93.  
  94. a.recycle();
  95.  
  96. init();
  97. }
  98.  
  99. private void init() {
  100. super.setScaleType(SCALE_TYPE);
  101. mReady = true;
  102.  
  103. if (mSetupPending) {
  104. setup();
  105. mSetupPending = false;
  106. }
  107. }
  108.  
  109. @Override
  110. public ScaleType getScaleType() {
  111. return SCALE_TYPE;
  112. }
  113.  
  114. @Override
  115. public void setScaleType(ScaleType scaleType) {
  116. if (scaleType != SCALE_TYPE) {
  117. throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
  118. }
  119. }
  120.  
  121. @Override
  122. public void setAdjustViewBounds(boolean adjustViewBounds) {
  123. if (adjustViewBounds) {
  124. throw new IllegalArgumentException("adjustViewBounds not supported.");
  125. }
  126. }
  127.  
  128. @Override
  129. protected void onDraw(Canvas canvas) {
  130. if (mBitmap == null) {
  131. return;
  132. }
  133.  
  134. if (mFillColor != Color.TRANSPARENT) {
  135. canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mFillPaint);
  136. }
  137. canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mDrawableRadius, mBitmapPaint);
  138. if (mBorderWidth != 0) {
  139. canvas.drawCircle(getWidth() / 2.0f, getHeight() / 2.0f, mBorderRadius, mBorderPaint);
  140. }
  141. }
  142.  
  143. @Override
  144. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  145. super.onSizeChanged(w, h, oldw, oldh);
  146. setup();
  147. }
  148.  
  149. public int getBorderColor() {
  150. return mBorderColor;
  151. }
  152.  
  153. public void setBorderColor(@ColorInt int borderColor) {
  154. if (borderColor == mBorderColor) {
  155. return;
  156. }
  157.  
  158. mBorderColor = borderColor;
  159. mBorderPaint.setColor(mBorderColor);
  160. invalidate();
  161. }
  162.  
  163. public void setBorderColorResource(@ColorRes int borderColorRes) {
  164. setBorderColor(getContext().getResources().getColor(borderColorRes));
  165. }
  166.  
  167. public int getFillColor() {
  168. return mFillColor;
  169. }
  170.  
  171. public void setFillColor(@ColorInt int fillColor) {
  172. if (fillColor == mFillColor) {
  173. return;
  174. }
  175.  
  176. mFillColor = fillColor;
  177. mFillPaint.setColor(fillColor);
  178. invalidate();
  179. }
  180.  
  181. public void setFillColorResource(@ColorRes int fillColorRes) {
  182. setFillColor(getContext().getResources().getColor(fillColorRes));
  183. }
  184.  
  185. public int getBorderWidth() {
  186. return mBorderWidth;
  187. }
  188.  
  189. public void setBorderWidth(int borderWidth) {
  190. if (borderWidth == mBorderWidth) {
  191. return;
  192. }
  193.  
  194. mBorderWidth = borderWidth;
  195. setup();
  196. }
  197.  
  198. public boolean isBorderOverlay() {
  199. return mBorderOverlay;
  200. }
  201.  
  202. public void setBorderOverlay(boolean borderOverlay) {
  203. if (borderOverlay == mBorderOverlay) {
  204. return;
  205. }
  206.  
  207. mBorderOverlay = borderOverlay;
  208. setup();
  209. }
  210.  
  211. @Override
  212. public void setImageBitmap(Bitmap bm) {
  213. super.setImageBitmap(bm);
  214. mBitmap = bm;
  215. setup();
  216. }
  217.  
  218. @Override
  219. public void setImageDrawable(Drawable drawable) {
  220. super.setImageDrawable(drawable);
  221. mBitmap = getBitmapFromDrawable(drawable);
  222. setup();
  223. }
  224.  
  225. @Override
  226. public void setImageResource(@DrawableRes int resId) {
  227. super.setImageResource(resId);
  228. mBitmap = getBitmapFromDrawable(getDrawable());
  229. setup();
  230. }
  231.  
  232. @Override
  233. public void setImageURI(Uri uri) {
  234. super.setImageURI(uri);
  235. mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null;
  236. setup();
  237. }
  238.  
  239. @Override
  240. public void setColorFilter(ColorFilter cf) {
  241. if (cf == mColorFilter) {
  242. return;
  243. }
  244.  
  245. mColorFilter = cf;
  246. mBitmapPaint.setColorFilter(mColorFilter);
  247. invalidate();
  248. }
  249.  
  250. private Bitmap getBitmapFromDrawable(Drawable drawable) {
  251. if (drawable == null) {
  252. return null;
  253. }
  254.  
  255. if (drawable instanceof BitmapDrawable) {
  256. return ((BitmapDrawable) drawable).getBitmap();
  257. }
  258.  
  259. try {
  260. Bitmap bitmap;
  261.  
  262. if (drawable instanceof ColorDrawable) {
  263. bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
  264. } else {
  265. bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
  266. }
  267.  
  268. Canvas canvas = new Canvas(bitmap);
  269. drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
  270. drawable.draw(canvas);
  271. return bitmap;
  272. } catch (Exception e) {
  273. e.printStackTrace();
  274. return null;
  275. }
  276. }
  277.  
  278. private void setup() {
  279. if (!mReady) {
  280. mSetupPending = true;
  281. return;
  282. }
  283.  
  284. if (getWidth() == 0 && getHeight() == 0) {
  285. return;
  286. }
  287.  
  288. if (mBitmap == null) {
  289. invalidate();
  290. return;
  291. }
  292.  
  293. mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
  294.  
  295. mBitmapPaint.setAntiAlias(true);
  296. mBitmapPaint.setShader(mBitmapShader);
  297.  
  298. mBorderPaint.setStyle(Paint.Style.STROKE);
  299. mBorderPaint.setAntiAlias(true);
  300. mBorderPaint.setColor(mBorderColor);
  301. mBorderPaint.setStrokeWidth(mBorderWidth);
  302.  
  303. mFillPaint.setStyle(Paint.Style.FILL);
  304. mFillPaint.setAntiAlias(true);
  305. mFillPaint.setColor(mFillColor);
  306.  
  307. mBitmapHeight = mBitmap.getHeight();
  308. mBitmapWidth = mBitmap.getWidth();
  309.  
  310. mBorderRect.set(0, 0, getWidth(), getHeight());
  311. mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
  312.  
  313. mDrawableRect.set(mBorderRect);
  314. if (!mBorderOverlay) {
  315. mDrawableRect.inset(mBorderWidth, mBorderWidth);
  316. }
  317. mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
  318.  
  319. updateShaderMatrix();
  320. invalidate();
  321. }
  322.  
  323. private void updateShaderMatrix() {
  324. float scale;
  325. float dx = 0;
  326. float dy = 0;
  327.  
  328. mShaderMatrix.set(null);
  329.  
  330. if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
  331. scale = mDrawableRect.height() / (float) mBitmapHeight;
  332. dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
  333. } else {
  334. scale = mDrawableRect.width() / (float) mBitmapWidth;
  335. dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
  336. }
  337.  
  338. mShaderMatrix.setScale(scale, scale);
  339. mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
  340.  
  341. mBitmapShader.setLocalMatrix(mShaderMatrix);
  342. }
  343.  
  344. }

这样就实现了所需要的效果。

圆形的Volley.NetworkImageView控件的实现的更多相关文章

  1. Android圆形图片--自己定义控件

    Android圆形图片控件效果图例如以下: 代码例如以下: RoundImageView.java package com.dxd.roundimageview; import android.con ...

  2. iOS项目开发实战——自己定义圆形进度提示控件

    iOS中默认的进度条是水平方向的进度条,这往往不能满足我们的需求. 可是我们能够自己定义类似的圆形的进度提示控件,主要使用iOS中的画图机制来实现. 这里我们要实现一个通过button点击然后圆形进度 ...

  3. Android常用酷炫控件(开源项目)github地址汇总

    转载一个很牛逼的控件收集帖... 第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.Gri ...

  4. Android 常用炫酷控件(开源项目)git地址汇总

    第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.P ...

  5. Android 开源控件与常用开发框架开发工具类

    Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...

  6. 如何自定义iOS中的控件

    本文译自 How to build a custom control in iOS .大家要是有什么问题,可以直接在 twitter 上联系原作者,当然也可以在最后的评论中回复我. 在开发过程中,有时 ...

  7. Android菜单menu控件大全

    下载:http://www.see-source.com/androidwidget/list.html?type=16 Android-NewPopupMenu 使用PopupWindow实现的Po ...

  8. VisionPro控件的使用 C# 开发篇

    VisionPro 常用控件的说明 工具设置窗体 CogPMAlignEditV2  [ 模版匹配设置窗体控件 ] CogPMAlignEditV2.Subject : 工具关联对象 如:CogPMA ...

  9. volley三种基本请求图片的方式与Lru的基本使用:正常的加载+含有Lru缓存的加载+Volley控件networkImageview的使用

    首先做出全局的请求队列 package com.qg.lizhanqi.myvolleydemo; import android.app.Application; import com.android ...

随机推荐

  1. JS判断form内所有表单是否为空

    function checkForm(){ var input_cart=document.getElementsByTagName("INPUT"); for(var   i=0 ...

  2. java_easyui体系之目录 [转]

    摘要:简单介绍form的提交方式.与validatebox的结合使用. 一:form简介 Easyui中的form有两种提交方式.结合自己新添加的一种ajax提交方式.本文简单说明form的三种提交方 ...

  3. QML的一些基础的区分

    什么时候用Item什么时候用Rectangle? 什么时候用Row什么时候用RowLayout? 这2个问题经常会让人迷糊. 什么时候用Item,就是你要做一个组件,这个组件是一个复合的组件,组件有部 ...

  4. iOS开发拓展篇—应用之间的跳转和数据传递

    iOS开发拓展篇—应用之间的跳转和数据传 说明:本文介绍app如何打开另一个app,并且传递数据. 一.简单说明 新建两个应用,分别为应用A和应用B. 实现要求:在appA的页面中点击对应的按钮,能够 ...

  5. Android SurfaceView

    今天介绍一下SurfaceView的用法,SurfaceView一般与SurfaceHolder结合使用,SurfaceHolder用于向与之关联的SurfaceView上绘图,调用SurfaceVi ...

  6. 排序小结(C++版)

    一.快速排序 #include <iostream> using namespace std; int adjust(int a[],int start,int end) { int i, ...

  7. 关于servlet的filter

    Servlet过滤器 2009-12-08 23:12:44|  分类: Java|举报|字号 订阅     一.什么是Servlet过滤器 过滤器是在数据交互之间过滤数据的中间组件,独立于任何平台或 ...

  8. js中的Bom对象模型

    Bom可以对浏览器的窗口进行访问和操作.使用Bom,开发者可以移动窗口,改变状态栏中的文本以及执行其他与页面内容不直接相关的动作. window对象: 1.窗口操作 其中moveTo,moveBy是窗 ...

  9. How do I uninstall Java 7 and later versions on my Mac?

    How do I uninstall Java 7 and later versions on my Mac? http://www.java.com/en/download/help/mac_uni ...

  10. crackme1.exe解密过程

    那今天呢     在西普的做题过程中,发现这么一款.exe,我们来破解一下(当然不是简单的强制爆破,不是简单的打补丁) 我们先用PE  看看   它是用什么写的  有没有加壳什么的 很好   是VC6 ...