Android中TextView自動(dòng)適配文本大小的幾種解決方案
TextView文本大小自動(dòng)適配與TextView邊距的去除
標(biāo)題太難取了,其實(shí)本文主要就是講如何控制文本大小,讓其自動(dòng)適配寬度,其次我們還需要精準(zhǔn)控制Text的高度和寬度間距等屬性。
一般我們的布局都是分 match parent 和 wrap content 而他們的自動(dòng)方式又有所不同。下面看看都有哪些方式來實(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)題的名字比較長,產(chǎn)品要求不換行全部顯示出來"
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 的方式類似,一般是測量 TextView 字體所占的寬度與 TextView 控件的寬度對比,動(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ì)算寬度的方法抽取出來,我們可以可以得到一個(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)寬度+多布局的變長寬度效果呢。其實(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)效果如下:(該效果是去除邊距之后的對齊效果)


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

而不同的TestSize 它的間距還不同,比如上文中我們一個(gè)很小的 TextView 和一個(gè)很大的 TextView 在一起排列的時(shí)候,特別是大的 TextView 還是 AutoSize 的情況下,實(shí)現(xiàn)一些對齊效果就很難實(shí)現(xiàn),我們就需要考慮到去除間距,只保留上圖灰色的矩形框來繪制文本。
代碼如下:
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)對齊和絕大部分文本的展示效果了。
總結(jié)
到此這篇關(guān)于Android中TextView自動(dòng)適配文本大小的幾種解決方案的文章就介紹到這了,更多相關(guān)Android TextView自動(dòng)適配文本大小內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
刷新Activity中的scrollview示例(局部ui刷新)
代碼很簡單,但是很實(shí)用,適合在一個(gè)Activity中要刷新局部的UI,比如在掃描一維碼的時(shí)候,要把每次掃描的結(jié)果都顯示在界面上2014-01-01
Android判斷touch事件點(diǎn)是否在view范圍內(nèi)的方法
這篇文章主要介紹了Android判斷touch事件點(diǎn)是否在view范圍內(nèi)的方法,涉及Android事件響應(yīng)與view屬性操作的相關(guān)技巧,需要的朋友可以參考下2016-03-03
解決eclipse啟動(dòng)時(shí)報(bào)錯(cuò)Failed to create the Java Virtural Machine.問題的
這篇文章主要介紹了解決eclipse啟動(dòng)時(shí)報(bào)Failed to create the Java Virtural Machine.問題的方法,感興趣的小伙伴們可以參考一下2016-01-01
android PopupWindow 和 Activity彈出窗口實(shí)現(xiàn)方式
本人小菜一個(gè)。目前只見過兩種彈出框的實(shí)現(xiàn)方式,第一種是最常見的PopupWindow,第二種也就是Activity的方式是前幾天才見識過,需要的朋友可以參考下2012-11-11
Android開發(fā)中如何解決Fragment +Viewpager滑動(dòng)頁面重復(fù)加載的問題
這篇文章主要介紹了Android開發(fā)中如何解決Fragment +Viewpager滑動(dòng)頁面重復(fù)加載的問題 ,需要的朋友可以參考下2017-07-07

