29
29
* 4、多次setCompoundDrawablesRelative,图片会发生偏移 √
30
30
* 5、寻找一个合适的测量文字大小的时机,避免多次测量 √
31
31
* 6、在draw时,避免用取出旧的drawable的bounds绘制,需要预先取出并存储起来,还需要注意在存储bounds时是不是有平移过 √
32
- * 7、
32
+ * 7、foreground会受平移影响 √
33
+ * 8、如果是只有hint没有Text需要也需要测量出文字大小√
33
34
*/
34
35
@ SuppressWarnings ({"UnusedReturnValue" , "unused" , "SameParameterValue" })
35
36
public class DrawableTextView extends AppCompatTextView {
@@ -119,6 +120,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
119
120
}
120
121
}
121
122
123
+
122
124
protected void onFirstLayout (int left , int top , int right , int bottom ) {
123
125
measureTextWidth ();
124
126
measureTextHeight ();
@@ -182,10 +184,16 @@ protected void onDraw(Canvas canvas) {
182
184
this .canvasTransY = transY ;
183
185
}
184
186
}
185
-
186
187
super .onDraw (canvas );
187
188
}
188
189
190
+ @ Override
191
+ public void onDrawForeground (Canvas canvas ) {
192
+ //再次平移回去
193
+ canvas .translate (-canvasTransX , -canvasTransY );
194
+ super .onDrawForeground (canvas );
195
+ }
196
+
189
197
/**
190
198
* 计算drawable居中还需距离
191
199
* 如果左右两边都有图片,左图片居中则需要加上右侧图片占用的空间{@link #getCompoundPaddingEnd()},其他同理
@@ -225,7 +233,13 @@ protected int getCanvasTransY() {
225
233
protected void measureTextWidth () {
226
234
final Rect textBounds = new Rect ();
227
235
getLineBounds (0 , textBounds );
228
- final float width = getPaint ().measureText (getText ().toString ());
236
+ String text = "" ;
237
+ if (getText () != null && getText ().length () > 0 ) {
238
+ text = getText ().toString ();
239
+ } else if (getHint () != null && getHint ().length () > 0 ) {
240
+ text = getHint ().toString ();
241
+ }
242
+ final float width = getPaint ().measureText (text );
229
243
final float maxWidth = textBounds .width ();
230
244
mTextWidth = width <= maxWidth || maxWidth == 0 ? width : maxWidth ;
231
245
}
@@ -234,7 +248,8 @@ protected void measureTextWidth() {
234
248
* 获取文本的高度,通过{@link #getLineHeight}乘文本的行数
235
249
*/
236
250
protected void measureTextHeight () {
237
- if (getText ().length () > 0 )
251
+ if ((getText () != null && getText ().length () > 0 )
252
+ || (getHint () != null && getHint ().length () > 0 ))
238
253
mTextHeight = getLineHeight () * getLineCount ();
239
254
else
240
255
mTextHeight = 0 ;
@@ -257,19 +272,27 @@ public void setText(CharSequence text, BufferType type) {
257
272
258
273
/**
259
274
* 设置Drawable,并设置宽高
275
+ * 默认大小为Drawable的{@link Drawable#getBounds()} ,
276
+ * 如果Bounds宽高为0则,取Drawable的内部固定尺寸{@link Drawable#getIntrinsicHeight()}
260
277
*
261
278
* @param position {@link POSITION}
262
279
* @param drawable Drawable
263
- * @param width DX
264
- * @param height DX
280
+ * @param width Px
281
+ * @param height Px
265
282
*/
266
283
public void setDrawable (@ POSITION int position , @ Nullable Drawable drawable , @ Px int width , @ Px int height ) {
267
284
mDrawables [position ] = drawable ;
268
285
if (drawable != null ) {
269
286
Rect bounds = new Rect ();
270
287
if (width == -1 && height == -1 ) {
271
- bounds .right = drawable .getIntrinsicWidth ();
272
- bounds .bottom = drawable .getIntrinsicHeight ();
288
+ if (drawable .getBounds ().width () > 0 && drawable .getBounds ().height () > 0 ) {
289
+ //如果Bounds宽高大于0,则保持默认
290
+ final Rect origin = drawable .getBounds ();
291
+ bounds .set (origin .left , origin .top , origin .right , origin .bottom );
292
+ } else {
293
+ //否则取Drawable的内部大小
294
+ bounds .set (0 , 0 , drawable .getIntrinsicWidth (), drawable .getIntrinsicHeight ());
295
+ }
273
296
} else {
274
297
bounds .right = width ;
275
298
bounds .bottom = height ;
@@ -323,15 +346,19 @@ private void storeDrawables(@Nullable Drawable start, @Nullable Drawable top, @N
323
346
protected Drawable [] copyDrawables (boolean clearOffset ) {
324
347
Drawable [] drawables = Arrays .copyOf (getDrawables (), 4 );
325
348
//clear offset
326
- if (clearOffset ) {
327
- for (Drawable drawable : drawables ) {
328
- if (drawable != null ) {
329
- Rect bounds = drawable .getBounds ();
330
- bounds .offset (-bounds .left , -bounds .top );
331
- }
349
+ if (clearOffset )
350
+ clearOffset (drawables );
351
+
352
+ return drawables ;
353
+ }
354
+
355
+ private void clearOffset (Drawable ... drawables ) {
356
+ for (Drawable drawable : drawables ) {
357
+ if (drawable != null ) {
358
+ Rect bounds = drawable .getBounds ();
359
+ bounds .offset (-bounds .left , -bounds .top );
332
360
}
333
361
}
334
- return drawables ;
335
362
}
336
363
337
364
protected int dp2px (float dpValue ) {
@@ -389,18 +416,28 @@ public DrawableTextView setDrawableBottom(Drawable drawableBottom) {
389
416
return this ;
390
417
}
391
418
392
- public void setEnableCenterDrawables (boolean enable ) {
419
+ public DrawableTextView setEnableCenterDrawables (boolean enable ) {
420
+ if (enableCenterDrawables ) {
421
+ //清除之前的位移
422
+ clearOffset (mDrawables );
423
+ }
393
424
this .enableCenterDrawables = enable ;
425
+ return this ;
394
426
}
395
427
396
- public void setEnableTextInCenter (boolean enable ) {
428
+ public DrawableTextView setEnableTextInCenter (boolean enable ) {
397
429
this .enableTextInCenter = enable ;
430
+ return this ;
398
431
}
399
432
400
433
public boolean isEnableTextInCenter () {
401
434
return enableTextInCenter ;
402
435
}
403
436
437
+ public boolean isEnableCenterDrawables () {
438
+ return enableCenterDrawables ;
439
+ }
440
+
404
441
public Drawable [] getDrawables () {
405
442
return mDrawables ;
406
443
}
0 commit comments