Android自定義TextView實(shí)現(xiàn)文字圖片居中顯示的方法
最近有個(gè)需求是這樣的,人民幣的符號(hào)“¥”因?yàn)榘沧渴謾C(jī)系統(tǒng)的不一致導(dǎo)致符號(hào)不是完全一樣,所以用美工的給的圖片代替,考慮到用的地方比較多,所以想著寫一個(gè)繼承于線性布局的組合控件,后來一想,安卓中不是有TextView嗎,這個(gè)自帶圖片的控件,后來寫了個(gè)demo,因?yàn)槲沂怯玫腗atchParent,導(dǎo)致問題出現(xiàn),人民幣符號(hào)不是和文字一樣的居中,因此才有了這篇博文,讓我們來自定義TextView吧,這個(gè)場(chǎng)景用的比較多。
分析下TextView的源碼
我們先來分析下TextView的源碼,因?yàn)門extView有上下左右四個(gè)方向的圖片,上下咱就先不考慮了,因?yàn)橐话銇碚f圖片垂直居中是沒有問題的,我們就只處理這個(gè)left,和right方向上的圖片, 我們直接看TextView的ondraw方法,因?yàn)門extView 也是繼承自View,所有的繪制都將會(huì)在這里操作
<span style="font-size:18px;">int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop; int hspace = right - left - compoundPaddingRight - compoundPaddingLeft; // IMPORTANT: The coordinates computed are also used in invalidateDrawable() // Make sure to update invalidateDrawable() when changing this code. if (dr.mShowing[Drawables.LEFT] != null) { canvas.save(); canvas.translate(scrollX + mPaddingLeft + leftOffset, scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightLeft) / 2); dr.mShowing[Drawables.LEFT].draw(canvas); canvas.restore(); } // IMPORTANT: The coordinates computed are also used in invalidateDrawable() // Make sure to update invalidateDrawable() when changing this code. if (dr.mShowing[Drawables.RIGHT] != null) { canvas.save(); canvas.translate(scrollX + right - left - mPaddingRight - dr.mDrawableSizeRight - rightOffset, scrollY + compoundPaddingTop + (vspace - dr.mDrawableHeightRight) / 2); dr.mShowing[Drawables.RIGHT].draw(canvas); canvas.restore(); }</span>
從上面可以看到有個(gè)canvas.translate方法,大概意思是,save后,將畫布向X軸和Y軸分別平移了scrollX ..和scrollY,平移后,將left方向的圖片繪制上去,最后restore還原到上個(gè)畫布中,Right同理。
那這樣,咱基本上就明白原理,TextView的四個(gè)方向都是通過Canvas的translate來繪制到文字的上下左右了,那咱們就只改這個(gè)scrollX 和 scrollY就可以實(shí)現(xiàn)咱的需求了吧。
具體實(shí)現(xiàn)
1.下面寫有注釋,不是特別麻煩,適配drawableLeft 和 drawableRight圖片,PS,xml中不要設(shè)置Gravity,這樣就可以居中了,代碼如下:
<span style="font-size:18px;">package com.chaoxing.email.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Gravity; import android.widget.TextView; /** * use in xml * use in code */ public class EmailCenterTextView extends TextView { public EmailCenterTextView(Context context) { super(context); } public EmailCenterTextView(Context context, AttributeSet attrs) { super(context, attrs); } public EmailCenterTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { Drawable[] drawables = getCompoundDrawables(); if (null != drawables) { Drawable drawableLeft = drawables[0]; Drawable drawableRight = drawables[2]; float textWidth = getPaint().measureText(getText().toString()); if (null != drawableLeft) { setGravity(Gravity.START | Gravity.CENTER_VERTICAL); float contentWidth = textWidth + getCompoundDrawablePadding() + drawableLeft.getIntrinsicWidth(); if (getWidth() - contentWidth > 0) { canvas.translate((getWidth() - contentWidth - getPaddingRight() - getPaddingLeft()) / 2, 0); } } if (null != drawableRight) { setGravity(Gravity.END | Gravity.CENTER_VERTICAL); float contentWidth = textWidth + getCompoundDrawablePadding() + drawableRight.getIntrinsicWidth(); if (getWidth() - contentWidth > 0) { canvas.translate(-(getWidth() - contentWidth - getPaddingRight() - getPaddingLeft()) / 2, 0); } } if (null == drawableRight && null == drawableLeft) { setGravity(Gravity.CENTER); } } super.onDraw(canvas); } }</span>
更新效果圖(因?yàn)橹坝锌吹骄W(wǎng)友回復(fù),最近又用到了再更新下這個(gè)博客)
title是用的就是EmailCenterTextView,那個(gè)箭頭上下的就是設(shè)置的drawableRight,演示的未讀和垃圾箱EmailCenterTextView沒有設(shè)置圖片
以上這篇Android自定義TextView實(shí)現(xiàn)文字圖片居中顯示的方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android應(yīng)用啟動(dòng)白屏處理方案詳解
這篇文章主要為大家介紹了Android應(yīng)用啟動(dòng)白屏處理方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Android學(xué)習(xí)之AppWidget高級(jí)效果
這篇文章主要為大家詳細(xì)介紹了Android學(xué)習(xí)之AppWidget高級(jí)效果的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-08-08Flutter?頁面跳轉(zhuǎn)和傳值的實(shí)現(xiàn)
跳轉(zhuǎn)傳值是再普通不過的小功能了,在開發(fā)中會(huì)經(jīng)常用到,比如列表進(jìn)入詳情,本文主要介紹了Flutter?頁面跳轉(zhuǎn)和傳值的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-04-04Android簡單實(shí)現(xiàn)圓盤抽獎(jiǎng)界面
這篇文章主要介紹了Android簡單實(shí)現(xiàn)圓盤抽獎(jiǎng)界面的相關(guān)資料,需要的朋友可以參考下2016-01-01發(fā)布?Android?library?到?Maven?解析
這篇文章主要介紹了發(fā)布?Android?library到Maven解析,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09Android入門之Fragment嵌套Fragment的用法詳解
這篇文章主要為大家詳細(xì)介紹了Android中如何實(shí)現(xiàn)Fragment嵌套Fragment的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2023-02-02