Android中TextView自動(dòng)適配文本大小的幾種解決方案
TextView文本大小自動(dòng)適配與TextView邊距的去除
標(biāo)題太難取了,其實(shí)本文主要就是講如何控制文本大小,讓其自動(dòng)適配寬度,其次我們還需要精準(zhǔn)控制Text的高度和寬度間距等屬性。
一般我們的布局都是分 match parent 和 wrap content 而他們的自動(dòng)方式又有所不同。下面看看都有哪些方式來(lái)實(shí)現(xiàn)!
一、Autosizing的方式(固定寬度)
官方推出的TextView的Autosizing方式,在寬度固定的情況下,可以設(shè)置最大文本Size和最小文本Size和每次縮放粒度,非常方便的就能實(shí)現(xiàn)該功能。
<TextView
android:layout_width="340dp"
android:layout_height="50dp"
android:background="@drawable/shape_bg_008577"
android:gravity="center_vertical"
android:maxLines="1"
android:text="這是標(biāo)題,該標(biāo)題的名字比較長(zhǎng),產(chǎn)品要求不換行全部顯示出來(lái)"
android:textSize="18sp"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="18sp"
android:autoSizeMinTextSize="10sp"
android:autoSizeStepGranularity="1sp"/>- autoSizeTextType:設(shè)置 TextView 是否支持自動(dòng)改變文本大小,none 表示不支持,uniform 表示支持。
- autoSizeMinTextSize:最小文字大小,例如設(shè)置為10sp,表示文字最多只能縮小到10sp。
- autoSizeMaxTextSize:最大文字大小,例如設(shè)置為18sp,表示文字最多只能放大到18sp。
- autoSizeStepGranularity:縮放粒度,即每次文字大小變化的數(shù)值,例如設(shè)置為1sp,表示每次縮小或放大的值為1sp。
效果:

如果在Java代碼中使用,我們也可以這么用
TextView tvText = findViewById(R.id.tv_text); TextViewCompat.setAutoSizeTextTypeWithDefaults(tvText,TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM); TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(tvText,10,18,1, TypedValue.COMPLEX_UNIT_SP);
二、自定義View的方式(固定寬度)
github上有很多這種的TextView自定義,類似這樣的。
其核心思想和上面的 Autosizing 的方式類似,一般是測(cè)量 TextView 字體所占的寬度與 TextView 控件的寬度對(duì)比,動(dòng)態(tài)改變 TextView 的字體大小。
它們的類似用法如下:
<ru.igla.widget.AutoSizeTextView
android:id="@+id/tvFullscreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Long ancestry"
android:textColor="@android:color/black"
android:background="@android:color/white"
android:textSize="500sp"
android:maxLines="500"
android:gravity="center"
android:ellipsize="@null"
android:autoText="false"
android:autoLink="none"
android:linksClickable="false"
android:singleLine="false"
android:padding="0px"
android:includeFontPadding="false"
android:textAlignment="center"
android:typeface="normal"
android:layout_gravity="center"
android:textStyle="normal"
app:minTxtSize="8sp"
/>效果和方案一類似
三、使用工具類自行計(jì)算(非控件固定寬度)
把第二步中自定義View計(jì)算寬度的方法抽取出來(lái),我們可以可以得到一個(gè)工具類如下:
private void adjustTvTextSize(TextView tv, int maxWidth, String text) {
int avaiWidth = maxWidth - tv.getPaddingLeft() - tv.getPaddingRight();
if (avaiWidth <= 0) {
return;
}
TextPaint textPaintClone = new TextPaint(tv.getPaint());
float trySize = textPaintClone.getTextSize();
while (textPaintClone.measureText(text) > avaiWidth) {
trySize--;
textPaintClone.setTextSize(trySize);
}
tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}Demo如下:

右側(cè)的LinearLayout中需要包含2個(gè)文本 一個(gè)14sp 一個(gè)是30sp,同時(shí)居中但是要金額的文本自動(dòng)適配大小。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_15dp"
android:layout_marginRight="@dimen/d_15dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_job_detail_dollar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$"
android:textColor="@color/black"
android:textSize="@dimen/job_detail_message_size"/>
<TextView
android:id="@+id/text_view_hourly_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_2dp"
android:singleLine="true"
android:text="-"
android:textColor="@color/job_detail_black"
android:textSize="30sp" />
</LinearLayout>可以看到2個(gè)都是wrap content,那么如何實(shí)現(xiàn)這種適應(yīng)寬度+多布局的變長(zhǎng)寬度效果呢。其實(shí)就是需要我們調(diào)用方法手動(dòng)的計(jì)算金額TextView的寬度
int mFullNameTVMaxWidth = CommUtils.dip2px(60);
// mTextViewHourlyRate.setText(totalMoney);
// while (true) {
// float measureTextWidth = mTextViewHourlyRate.getPaint().measureText(totalMoney);
// if (measureTextWidth > mFullNameTVMaxWidth) {
// int textSize = (int) mTextViewHourlyRate.getTextSize();
// textSize = textSize - 2;
// mTextViewHourlyRate.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
// } else {
// break;
// }
// }
adjustTvTextSize(mTextViewHourlyRate,mFullNameTVMaxWidth,totalMoney)效果如下:(該效果是去除邊距之后的對(duì)齊效果)


四、去除TextView的邊距
我們都知道TextView繪制的時(shí)候并非是我們平常自定義View那種drawText,而是分為幾塊區(qū)域,基于基線繪制文本,并加入了上下左右的間距。

而不同的TestSize 它的間距還不同,比如上文中我們一個(gè)很小的 TextView 和一個(gè)很大的 TextView 在一起排列的時(shí)候,特別是大的 TextView 還是 AutoSize 的情況下,實(shí)現(xiàn)一些對(duì)齊效果就很難實(shí)現(xiàn),我們就需要考慮到去除間距,只保留上圖灰色的矩形框來(lái)繪制文本。
代碼如下:
public class NoPaddingTextView extends AppCompatTextView {
private Paint mPaint = getPaint();
private Rect mBounds = new Rect();
private Boolean mRemoveFontPadding = false;//是否去除字體內(nèi)邊距,true:去除 false:不去除
public NoPaddingTextView(Context context) {
super(context);
}
public NoPaddingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
initAttributes(context, attrs);
}
public NoPaddingTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttributes(context, attrs);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mRemoveFontPadding) {
calculateTextParams();
setMeasuredDimension(mBounds.right - mBounds.left, -mBounds.top + mBounds.bottom);
}
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
protected void onDraw(Canvas canvas) {
drawText(canvas);
}
/**
* 初始化屬性
*/
private void initAttributes(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NoPaddingTextView);
mRemoveFontPadding = typedArray.getBoolean(R.styleable.NoPaddingTextView_removeDefaultPadding, false);
typedArray.recycle();
}
/**
* 計(jì)算文本參數(shù)
*/
private String calculateTextParams() {
String text = getText().toString();
int textLength = text.length();
mPaint.getTextBounds(text, 0, textLength, mBounds);
if (textLength == 0) {
mBounds.right = mBounds.left;
}
return text;
}
/**
* 繪制文本
*/
private void drawText(Canvas canvas) {
String text = calculateTextParams();
int left = mBounds.left;
int bottom = mBounds.bottom;
mBounds.offset(-mBounds.left, -mBounds.top);
mPaint.setAntiAlias(true);
mPaint.setColor(getCurrentTextColor());
canvas.drawText(text, (float) (-left), (float) (mBounds.bottom - bottom), mPaint);
}
}使用:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_15dp"
android:layout_marginRight="@dimen/d_15dp"
android:gravity="center"
android:orientation="horizontal">
<com.guadou.componentservice.widget.view.NoPaddingTextView
android:id="@+id/tv_job_detail_dollar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="$"
android:textColor="@color/black"
android:background="@color/yellow"
android:textSize="@dimen/job_detail_message_size"
app:removeDefaultPadding="true" />
<com.guadou.componentservice.widget.view.NoPaddingTextView
android:id="@+id/text_view_hourly_rate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/d_2dp"
android:singleLine="true"
android:text="-"
android:background="@color/red"
android:textColor="@color/job_detail_black"
android:textSize="30sp"
app:removeDefaultPadding="true" />
</LinearLayout>效果如下:

到此我們就能隨心的控制 TextView 的大小和間距,想讓文本多大就多大,想在哪展示就在哪展示,很方便的實(shí)現(xiàn)對(duì)齊和絕大部分文本的展示效果了。
總結(jié)
到此這篇關(guān)于Android中TextView自動(dòng)適配文本大小的幾種解決方案的文章就介紹到這了,更多相關(guān)Android TextView自動(dòng)適配文本大小內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
簡(jiǎn)單介紹Android開發(fā)中的Activity控件的基本概念
這篇文章主要介紹了Android開發(fā)中的Activity控件的基本概念,Activity控件的使用是安卓開發(fā)的基礎(chǔ)之一,需要的朋友可以參考下2015-12-12
Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果
這篇文章主要介紹了Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09
Android如何實(shí)現(xiàn)時(shí)間線效果
這篇文章主要介紹了?Android如何實(shí)現(xiàn)時(shí)間線效果,下面文章圍繞?Android如何實(shí)現(xiàn)時(shí)間線效果的相關(guān)資料展開詳細(xì)內(nèi)容,具有一定的參考價(jià)值?,需要的朋友可以參考一下2021-11-11
Android之用PopupWindow實(shí)現(xiàn)彈出菜單的方法詳解
本篇文章是對(duì)在Android中,用PopupWindow實(shí)現(xiàn)彈出菜單的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
Android中顯示GIF動(dòng)畫的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android中顯示GIF動(dòng)畫的實(shí)現(xiàn)代碼,較為詳細(xì)的分析了Android調(diào)用GIF動(dòng)畫所涉及的頁(yè)面布局及功能實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
Android開發(fā)之OkHttpUtils的具體使用方法
這篇文章主要介紹了Android開發(fā)之OkHttpUtils的具體使用方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-08-08
關(guān)于Touch Panel AA區(qū)要做外擴(kuò)的原因解析
今天小編就為大家分享一篇關(guān)于Touch Panel AA區(qū)要做外擴(kuò)的原因解析,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12

