Android自定義TextView實(shí)現(xiàn)文字圖片居中顯示的方法
最近有個(gè)需求是這樣的,人民幣的符號(hào)“¥”因?yàn)榘沧渴謾C(jī)系統(tǒng)的不一致導(dǎo)致符號(hào)不是完全一樣,所以用美工的給的圖片代替,考慮到用的地方比較多,所以想著寫(xiě)一個(gè)繼承于線性布局的組合控件,后來(lái)一想,安卓中不是有TextView嗎,這個(gè)自帶圖片的控件,后來(lái)寫(xiě)了個(gè)demo,因?yàn)槲沂怯玫腗atchParent,導(dǎo)致問(wèn)題出現(xiàn),人民幣符號(hào)不是和文字一樣的居中,因此才有了這篇博文,讓我們來(lái)自定義TextView吧,這個(gè)場(chǎng)景用的比較多。
分析下TextView的源碼
我們先來(lái)分析下TextView的源碼,因?yàn)門(mén)extView有上下左右四個(gè)方向的圖片,上下咱就先不考慮了,因?yàn)橐话銇?lái)說(shuō)圖片垂直居中是沒(méi)有問(wèn)題的,我們就只處理這個(gè)left,和right方向上的圖片, 我們直接看TextView的ondraw方法,因?yàn)門(mé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后,將畫(huà)布向X軸和Y軸分別平移了scrollX ..和scrollY,平移后,將left方向的圖片繪制上去,最后restore還原到上個(gè)畫(huà)布中,Right同理。
那這樣,咱基本上就明白原理,TextView的四個(gè)方向都是通過(guò)Canvas的translate來(lái)繪制到文字的上下左右了,那咱們就只改這個(gè)scrollX 和 scrollY就可以實(shí)現(xiàn)咱的需求了吧。
具體實(shí)現(xiàn)
1.下面寫(xiě)有注釋?zhuān)皇翘貏e麻煩,適配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沒(méi)有設(shè)置圖片

以上這篇Android自定義TextView實(shí)現(xiàn)文字圖片居中顯示的方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android 實(shí)現(xiàn)抖音頭像底部彈框效果的實(shí)例代碼
這篇文章主要介紹了Android 實(shí)現(xiàn)抖音頭像底部彈框效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Android編程實(shí)現(xiàn)在一個(gè)程序中啟動(dòng)另一個(gè)程序的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)在一個(gè)程序中啟動(dòng)另一個(gè)程序的方法,結(jié)合實(shí)例形式分析了Android通過(guò)ResolveInfo類(lèi)來(lái)取得啟動(dòng)Acitivty類(lèi)名的方法來(lái)啟動(dòng)另一個(gè)程序的方法,需要的朋友可以參考下2017-02-02
Android Studio 合并module到統(tǒng)一文件夾的方法
這篇文章主要介紹了Android Studio 合并module到統(tǒng)一文件夾的方法,補(bǔ)充介紹了android studio關(guān)于同名資源文件的合并技巧,需要的朋友可以參考下2018-04-04
使用android-apktool來(lái)逆向(反編譯)APK包方法介紹
這篇文章主要介紹了使用android-apktool來(lái)逆向(反編譯)APK包方法介紹,本文講解了版本問(wèn)題、使用apktool、反編譯decode、rebuild重打包等內(nèi)容,需要的朋友可以參考下2015-04-04
HorizontalScrollView水平滾動(dòng)控件使用方法詳解
這篇文章主要為大家詳細(xì)介紹了HorizontalScrollView水平滾動(dòng)控件的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android自定義控件實(shí)現(xiàn)溫度旋轉(zhuǎn)按鈕效果
這篇文章主要給大家介紹了關(guān)于Android如何通過(guò)自定義控件實(shí)現(xiàn)溫度旋轉(zhuǎn)按鈕的效果,文中通過(guò)思路與方法一步步介紹的很詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們下面來(lái)一起看看吧。2016-12-12
Kotlin FrameLayout與ViewPager2控件實(shí)現(xiàn)滾動(dòng)廣告欄方法
這篇文章主要介紹了Kotlin FrameLayout與ViewPager2控件實(shí)現(xiàn)滾動(dòng)廣告欄,F(xiàn)rameLayout與ViewPager2是Android開(kāi)發(fā)中非常常見(jiàn)的布局組件,并且它不單單是一個(gè)幀布局組件,可以用它實(shí)現(xiàn)多種功能,感興趣的朋友一起來(lái)看看吧2022-12-12
JSON中optString和getString方法的區(qū)別
optString方法會(huì)在對(duì)應(yīng)的key中的值不存在的時(shí)候返回一個(gè)空字符串,但是getString會(huì)拋一個(gè)JSONException 。下面通過(guò)一段代碼給大家介紹JSON中optString和getString方法的區(qū)別,感興趣的朋友一起看看吧2017-07-07
Android ImageView Src 和Background 區(qū)別
這篇文章主要介紹了Android ImageView Src 和Background 區(qū)別的相關(guān)資料,需要的朋友可以參考下2016-09-09
Android?NDK入門(mén)初識(shí)(組件結(jié)構(gòu)開(kāi)發(fā)流程)
這篇文章主要為大家介紹了Android?NDK入門(mén)之初識(shí)組件結(jié)構(gòu)開(kāi)發(fā)流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

