0
点赞
收藏
分享

微信扫一扫

android开源系列:CircleImageView自定义圆形控件的使用


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. 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. true;  
70.   
71. if (mSetupPending) {  
72.             setup();  
73. 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. 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);  
96. 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. new Canvas(bitmap);  
172. 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. true;  
183. return;  
184.         }  
185.   
186. if (mBitmap == null) {  
187. return;  
188.         }  
189.   
190. new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);  
191.   
192. true);  
193.         mBitmapPaint.setShader(mBitmapShader);  
194.   
195.         mBorderPaint.setStyle(Paint.Style.STROKE);  
196. true);  
197.         mBorderPaint.setColor(mBorderColor);  
198.         mBorderPaint.setStrokeWidth(mBorderWidth);  
199.   
200.         mBitmapHeight = mBitmap.getHeight();  
201.         mBitmapWidth = mBitmap.getWidth();  
202.   
203. 0, 0, getWidth(), getHeight());  
204. 2, (mBorderRect.width() - mBorderWidth) / 2);  
205.   
206.         mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);  
207. 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. null);  
219.   
220. if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {  
221. float) mBitmapHeight;  
222. 0.5f;  
223. else {  
224. float) mBitmapWidth;  
225. 0.5f;  
226.         }  
227.   
228.         mShaderMatrix.setScale(scale, scale);  
229. 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. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. xmlns:app="http://schemas.android.com/apk/res-auto"  
4. android:layout_width="match_parent"  
5. android:layout_height="match_parent"  
6. android:orientation="vertical" >  
7. <RelativeLayout  
8. android:layout_width="match_parent"  
9. android:layout_height="0dp"  
10. android:layout_weight="1"  
11. android:padding="@dimen/base_padding"  
12. android:background="@color/light">  
13.   
14. <de.hdodenhof.circleimageview.CircleImageView  
15. android:layout_width="160dp"  
16. android:layout_height="160dp"  
17. android:layout_centerInParent="true"  
18. android:src="@drawable/demo"  
19. app:border_width="2dp"  
20. app:border_color="@color/dark" />  
21.   
22. </RelativeLayout>  
23.   
24. <RelativeLayout  
25. android:layout_width="match_parent"  
26. android:layout_height="0dp"  
27. android:layout_weight="1"  
28. android:padding="@dimen/base_padding"  
29. android:background="@color/dark">  
30.   
31. <de.hdodenhof.circleimageview.CircleImageView  
32. android:layout_width="160dp"  
33. android:layout_height="160dp"  
34. android:layout_centerInParent="true"  
35. android:src="@drawable/lena"  
36. app:border_width="2dp"  
37. app:border_color="@color/light" />  
38.   
39. </RelativeLayout>  
40.   
41. </LinearLayout>



效果:

android开源系列:CircleImageView自定义圆形控件的使用_自定义圆形头像




注意:有些开发者可能也发现了,如果我们需要一个圆形的ImageButton的话,其实,我们没有必要自己写。如果ImageButton的图标是固定不变的,我们完全可以让设计师给我设计一个圆形的图片,然后直接设置再ImageButton上就可以了。但是,请注意,我们这里的圆形ImageView是自定义控件,也即是:无论你设置的图片是什么样的,显示出来的就是圆的。比如:易信中用户头像的设置,无论用户拍什么的照片,显示出来都是一个圆的。

拓展阅读

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

https://github.com/vinc3m1/RoundedImageView

举报

相关推荐

0 条评论