Android中TextView自動適配文本大小的幾種解決方案
TextView文本大小自動適配與TextView邊距的去除
標題太難取了,其實本文主要就是講如何控制文本大小,讓其自動適配寬度,其次我們還需要精準控制Text的高度和寬度間距等屬性。
一般我們的布局都是分 match parent 和 wrap content 而他們的自動方式又有所不同。下面看看都有哪些方式來實現(xiàn)!
一、Autosizing的方式(固定寬度)
官方推出的TextView的Autosizing方式,在寬度固定的情況下,可以設置最大文本Size和最小文本Size和每次縮放粒度,非常方便的就能實現(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="這是標題,該標題的名字比較長,產品要求不換行全部顯示出來"
android:textSize="18sp"
android:autoSizeTextType="uniform"
android:autoSizeMaxTextSize="18sp"
android:autoSizeMinTextSize="10sp"
android:autoSizeStepGranularity="1sp"/>- autoSizeTextType:設置 TextView 是否支持自動改變文本大小,none 表示不支持,uniform 表示支持。
- autoSizeMinTextSize:最小文字大小,例如設置為10sp,表示文字最多只能縮小到10sp。
- autoSizeMaxTextSize:最大文字大小,例如設置為18sp,表示文字最多只能放大到18sp。
- autoSizeStepGranularity:縮放粒度,即每次文字大小變化的數值,例如設置為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 控件的寬度對比,動態(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"
/>效果和方案一類似
三、使用工具類自行計算(非控件固定寬度)
把第二步中自定義View計算寬度的方法抽取出來,我們可以可以得到一個工具類如下:
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如下:

右側的LinearLayout中需要包含2個文本 一個14sp 一個是30sp,同時居中但是要金額的文本自動適配大小。
<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個都是wrap content,那么如何實現(xiàn)這種適應寬度+多布局的變長寬度效果呢。其實就是需要我們調用方法手動的計算金額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繪制的時候并非是我們平常自定義View那種drawText,而是分為幾塊區(qū)域,基于基線繪制文本,并加入了上下左右的間距。

而不同的TestSize 它的間距還不同,比如上文中我們一個很小的 TextView 和一個很大的 TextView 在一起排列的時候,特別是大的 TextView 還是 AutoSize 的情況下,實現(xiàn)一些對齊效果就很難實現(xiàn),我們就需要考慮到去除間距,只保留上圖灰色的矩形框來繪制文本。
代碼如下:
public class NoPaddingTextView extends AppCompatTextView {
private Paint mPaint = getPaint();
private Rect mBounds = new Rect();
private Boolean mRemoveFontPadding = false;//是否去除字體內邊距,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();
}
/**
* 計算文本參數
*/
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 的大小和間距,想讓文本多大就多大,想在哪展示就在哪展示,很方便的實現(xiàn)對齊和絕大部分文本的展示效果了。
總結
到此這篇關于Android中TextView自動適配文本大小的幾種解決方案的文章就介紹到這了,更多相關Android TextView自動適配文本大小內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
簡單介紹Android開發(fā)中的Activity控件的基本概念
這篇文章主要介紹了Android開發(fā)中的Activity控件的基本概念,Activity控件的使用是安卓開發(fā)的基礎之一,需要的朋友可以參考下2015-12-12
Android中自定義PopupWindow實現(xiàn)彈出框并帶有動畫效果
這篇文章主要介紹了Android中自定義PopupWindow實現(xiàn)彈出框并帶有動畫效果的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09
Android之用PopupWindow實現(xiàn)彈出菜單的方法詳解
本篇文章是對在Android中,用PopupWindow實現(xiàn)彈出菜單的方法進行了詳細的分析介紹,需要的朋友參考下2013-06-06
Android開發(fā)之OkHttpUtils的具體使用方法
這篇文章主要介紹了Android開發(fā)之OkHttpUtils的具體使用方法,非常具有實用價值,需要的朋友可以參考下2017-08-08
關于Touch Panel AA區(qū)要做外擴的原因解析
今天小編就為大家分享一篇關于Touch Panel AA區(qū)要做外擴的原因解析,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12

