-
FROM: githhub;
-
自定义的ImageView类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
|
package
com.example.testcircleimageview;
import
android.content.Context;
import
android.content.res.TypedArray;
import
android.graphics.Bitmap;
import
android.graphics.BitmapShader;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.ColorFilter;
import
android.graphics.Matrix;
import
android.graphics.Paint;
import
android.graphics.RectF;
import
android.graphics.Shader;
import
android.graphics.drawable.BitmapDrawable;
import
android.graphics.drawable.ColorDrawable;
import
android.graphics.drawable.Drawable;
import
android.net.Uri;
import
android.util.AttributeSet;
import
android.widget.ImageView;
public
class
CircleImageView
extends
ImageView {
private
static
final
ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
private
static
final
Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private
static
final
int
COLORDRAWABLE_DIMENSION =
2
;
private
static
final
int
DEFAULT_BORDER_WIDTH =
0
;
private
static
final
int
DEFAULT_BORDER_COLOR = Color.BLACK;
private
final
RectF mDrawableRect =
new
RectF();
private
final
RectF mBorderRect =
new
RectF();
private
final
Matrix mShaderMatrix =
new
Matrix();
private
final
Paint mBitmapPaint =
new
Paint();
private
final
Paint mBorderPaint =
new
Paint();
private
int
mBorderColor = DEFAULT_BORDER_COLOR;
private
int
mBorderWidth = DEFAULT_BORDER_WIDTH;
private
Bitmap mBitmap;
private
BitmapShader mBitmapShader;
private
int
mBitmapWidth;
private
int
mBitmapHeight;
private
float
mDrawableRadius;
private
float
mBorderRadius;
private
ColorFilter mColorFilter;
private
boolean
mReady;
private
boolean
mSetupPending;
public
CircleImageView(Context context) {
super
(context);
init();
}
public
CircleImageView(Context context, AttributeSet attrs) {
this
(context, attrs,
0
);
}
public
CircleImageView(Context context, AttributeSet attrs,
int
defStyle) {
super
(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle,
0
);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);
a.recycle();
init();
}
private
void
init() {
super
.setScaleType(SCALE_TYPE);
mReady =
true
;
if
(mSetupPending) {
setup();
mSetupPending =
false
;
}
}
@Override
public
ScaleType getScaleType() {
return
SCALE_TYPE;
}
@Override
public
void
setScaleType(ScaleType scaleType) {
if
(scaleType != SCALE_TYPE) {
throw
new
IllegalArgumentException(String.format(
"ScaleType %s not supported."
, scaleType));
}
}
@Override
public
void
setAdjustViewBounds(
boolean
adjustViewBounds) {
if
(adjustViewBounds) {
throw
new
IllegalArgumentException(
"adjustViewBounds not supported."
);
}
}
@Override
protected
void
onDraw(Canvas canvas) {
if
(getDrawable() ==
null
) {
return
;
}
canvas.drawCircle(getWidth() /
2
, getHeight() /
2
, mDrawableRadius, mBitmapPaint);
if
(mBorderWidth !=
0
) {
canvas.drawCircle(getWidth() /
2
, getHeight() /
2
, mBorderRadius, mBorderPaint);
}
}
@Override
protected
void
onSizeChanged(
int
w,
int
h,
int
oldw,
int
oldh) {
super
.onSizeChanged(w, h, oldw, oldh);
setup();
}
public
int
getBorderColor() {
return
mBorderColor;
}
public
void
setBorderColor(
int
borderColor) {
if
(borderColor == mBorderColor) {
return
;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public
int
getBorderWidth() {
return
mBorderWidth;
}
public
void
setBorderWidth(
int
borderWidth) {
if
(borderWidth == mBorderWidth) {
return
;
}
mBorderWidth = borderWidth;
setup();
}
@Override
public
void
setImageBitmap(Bitmap bm) {
super
.setImageBitmap(bm);
mBitmap = bm;
setup();
}
@Override
public
void
setImageDrawable(Drawable drawable) {
super
.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
setup();
}
@Override
public
void
setImageResource(
int
resId) {
super
.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public
void
setImageURI(Uri uri) {
super
.setImageURI(uri);
mBitmap = getBitmapFromDrawable(getDrawable());
setup();
}
@Override
public
void
setColorFilter(ColorFilter cf) {
if
(cf == mColorFilter) {
return
;
}
mColorFilter = cf;
mBitmapPaint.setColorFilter(mColorFilter);
invalidate();
}
private
Bitmap getBitmapFromDrawable(Drawable drawable) {
if
(drawable ==
null
) {
return
null
;
}
if
(drawable
instanceof
BitmapDrawable) {
return
((BitmapDrawable) drawable).getBitmap();
}
try
{
Bitmap bitmap;
if
(drawable
instanceof
ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
}
else
{
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas =
new
Canvas(bitmap);
drawable.setBounds(
0
,
0
, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return
bitmap;
}
catch
(OutOfMemoryError e) {
return
null
;
}
}
private
void
setup() {
if
(!mReady) {
mSetupPending =
true
;
return
;
}
if
(mBitmap ==
null
) {
return
;
}
mBitmapShader =
new
BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(
true
);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(
true
);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
mBorderRect.set(
0
,
0
, getWidth(), getHeight());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) /
2
, (mBorderRect.width() - mBorderWidth) /
2
);
mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);
mDrawableRadius = Math.min(mDrawableRect.height() /
2
, mDrawableRect.width() /
2
);
updateShaderMatrix();
invalidate();
}
private
void
updateShaderMatrix() {
float
scale;
float
dx =
0
;
float
dy =
0
;
mShaderMatrix.set(
null
);
if
(mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (
float
) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) *
0
.5f;
}
else
{
scale = mDrawableRect.width() / (
float
) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) *
0
.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((
int
) (dx +
0
.5f) + mBorderWidth, (
int
) (dy +
0
.5f) + mBorderWidth);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}
|
2.在attrs文件中添加:
1
2
3
4
|
<declare-styleable name=
"CircleImageView"
>
<attr name=
"border_width"
format=
"dimension"
/>
<attr name=
"border_color"
format=
"color"
/>
</declare-styleable>
|
3.在布局文件中申明使用:
1
2
3
4
5
6
|
<com.example.testcircleimageview.CircleImageView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:src=
"@drawable/icon"
app:border_color=
"@android:color/black"
app:border_width=
"10dp"
/>
|
4.效果:
本文转自wauoen51CTO博客,原文链接:http://blog.51cto.com/7183397/1608761 ,如需转载请自行联系原作者