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開(kāi)發(fā)中的Activity控件的基本概念
這篇文章主要介紹了Android開(kāi)發(fā)中的Activity控件的基本概念,Activity控件的使用是安卓開(kāi)發(fā)的基礎(chǔ)之一,需要的朋友可以參考下2015-12-12Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果
這篇文章主要介紹了Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09Android如何實(shí)現(xiàn)時(shí)間線效果
這篇文章主要介紹了?Android如何實(shí)現(xiàn)時(shí)間線效果,下面文章圍繞?Android如何實(shí)現(xiàn)時(shí)間線效果的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,具有一定的參考價(jià)值?,需要的朋友可以參考一下2021-11-11Android之用PopupWindow實(shí)現(xiàn)彈出菜單的方法詳解
本篇文章是對(duì)在Android中,用PopupWindow實(shí)現(xiàn)彈出菜單的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android中顯示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-10Android開(kāi)發(fā)之OkHttpUtils的具體使用方法
這篇文章主要介紹了Android開(kāi)發(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