2929 * 4、多次setCompoundDrawablesRelative,图片会发生偏移 √
3030 * 5、寻找一个合适的测量文字大小的时机,避免多次测量 √
3131 * 6、在draw时,避免用取出旧的drawable的bounds绘制,需要预先取出并存储起来,还需要注意在存储bounds时是不是有平移过 √
32- * 7、
32+ * 7、foreground会受平移影响 √
33+ * 8、如果是只有hint没有Text需要也需要测量出文字大小√
3334 */
3435@ SuppressWarnings ({"UnusedReturnValue" , "unused" , "SameParameterValue" })
3536public class DrawableTextView extends AppCompatTextView {
@@ -119,6 +120,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
119120 }
120121 }
121122
123+
122124 protected void onFirstLayout (int left , int top , int right , int bottom ) {
123125 measureTextWidth ();
124126 measureTextHeight ();
@@ -182,10 +184,16 @@ protected void onDraw(Canvas canvas) {
182184 this .canvasTransY = transY ;
183185 }
184186 }
185-
186187 super .onDraw (canvas );
187188 }
188189
190+ @ Override
191+ public void onDrawForeground (Canvas canvas ) {
192+ //再次平移回去
193+ canvas .translate (-canvasTransX , -canvasTransY );
194+ super .onDrawForeground (canvas );
195+ }
196+
189197 /**
190198 * 计算drawable居中还需距离
191199 * 如果左右两边都有图片,左图片居中则需要加上右侧图片占用的空间{@link #getCompoundPaddingEnd()},其他同理
@@ -225,7 +233,13 @@ protected int getCanvasTransY() {
225233 protected void measureTextWidth () {
226234 final Rect textBounds = new Rect ();
227235 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 );
229243 final float maxWidth = textBounds .width ();
230244 mTextWidth = width <= maxWidth || maxWidth == 0 ? width : maxWidth ;
231245 }
@@ -234,7 +248,8 @@ protected void measureTextWidth() {
234248 * 获取文本的高度,通过{@link #getLineHeight}乘文本的行数
235249 */
236250 protected void measureTextHeight () {
237- if (getText ().length () > 0 )
251+ if ((getText () != null && getText ().length () > 0 )
252+ || (getHint () != null && getHint ().length () > 0 ))
238253 mTextHeight = getLineHeight () * getLineCount ();
239254 else
240255 mTextHeight = 0 ;
@@ -257,19 +272,27 @@ public void setText(CharSequence text, BufferType type) {
257272
258273 /**
259274 * 设置Drawable,并设置宽高
275+ * 默认大小为Drawable的{@link Drawable#getBounds()} ,
276+ * 如果Bounds宽高为0则,取Drawable的内部固定尺寸{@link Drawable#getIntrinsicHeight()}
260277 *
261278 * @param position {@link POSITION}
262279 * @param drawable Drawable
263- * @param width DX
264- * @param height DX
280+ * @param width Px
281+ * @param height Px
265282 */
266283 public void setDrawable (@ POSITION int position , @ Nullable Drawable drawable , @ Px int width , @ Px int height ) {
267284 mDrawables [position ] = drawable ;
268285 if (drawable != null ) {
269286 Rect bounds = new Rect ();
270287 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+ }
273296 } else {
274297 bounds .right = width ;
275298 bounds .bottom = height ;
@@ -323,15 +346,19 @@ private void storeDrawables(@Nullable Drawable start, @Nullable Drawable top, @N
323346 protected Drawable [] copyDrawables (boolean clearOffset ) {
324347 Drawable [] drawables = Arrays .copyOf (getDrawables (), 4 );
325348 //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 );
332360 }
333361 }
334- return drawables ;
335362 }
336363
337364 protected int dp2px (float dpValue ) {
@@ -389,18 +416,28 @@ public DrawableTextView setDrawableBottom(Drawable drawableBottom) {
389416 return this ;
390417 }
391418
392- public void setEnableCenterDrawables (boolean enable ) {
419+ public DrawableTextView setEnableCenterDrawables (boolean enable ) {
420+ if (enableCenterDrawables ) {
421+ //清除之前的位移
422+ clearOffset (mDrawables );
423+ }
393424 this .enableCenterDrawables = enable ;
425+ return this ;
394426 }
395427
396- public void setEnableTextInCenter (boolean enable ) {
428+ public DrawableTextView setEnableTextInCenter (boolean enable ) {
397429 this .enableTextInCenter = enable ;
430+ return this ;
398431 }
399432
400433 public boolean isEnableTextInCenter () {
401434 return enableTextInCenter ;
402435 }
403436
437+ public boolean isEnableCenterDrawables () {
438+ return enableCenterDrawables ;
439+ }
440+
404441 public Drawable [] getDrawables () {
405442 return mDrawables ;
406443 }
0 commit comments