歡迎光臨
每天分享高質量文章

官方提供的自動改變文字大小的“TextView”

作者:孟校長

連結:https://www.jianshu.com/p/699a8cae05ce

前言

上一篇文章還是今年四月份寫的,期間也嘗試寫過幾篇文章, 但是都因繁忙的工作只能暫時的放下。此刻其實手上還是有很多需求沒有完成,但是我覺著有必要把今天學到的這個知識點分享一下。

因為,關於這個知識點雖然很簡單,但是卻發現目前網上的一些文章寫的真是不怎麼用心,都是陳述這個問題很好解決,然後文章也附上了實現的程式碼,但是按照作者寫的實現方式本地去執行卻發現是無效的。下麵我來描述下這個問題的場景以及解決方案。

關於AutoSizeableTextView

公司上個版本中有這樣一個需求,要求在一個串列中的每個條目中展示字數不限個數的文字。而且每個條目的寬度都是固定的,展示的文字如果過長,不可以用省略號顯示,只能動態的調整(縮小)文字的字號來達到文字能完全顯示的效果,而且要限一行展示。關於這個效果,其實目前android官方已經提供了實現方式。那就是AutoSizeableTextView。

文章的標題我之所以給AutoSizeableTextView加了雙引號,其實是因為,我們如果只看這個名字,會覺著這應該是android新推出的一個功能更強大的TextView控制元件(起初我也是這樣認為的)。但如果我們點進到原始碼中會發現,其實它是一個介面。

關於這個介面,詳情還請自行閱讀哈。

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview

在Android 8.0,android提供了這樣一個介面用來實現上面我所描述的這個效果。

當然,官方推出這個介面之前,估計已經有很多網上的案例透過自定義View的方式實現了這個效果。

可必須承認的一點是,人家官方提供的東西應該比你自己實現的東西要靠譜些吧(大神請見諒)。雖然這個介面是8.0才提出的,但是為了讓以前的低版本也能實現這個效果,官方提供了相應的相容舉措的,下麵我針對兩種方式進行介紹。

使用

在XML中設定

 


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" // 加入app名稱空間
    android:layout_width="match_parent"
    android:layout_height="@dimen/dimen_45">

    <android.support.v7.widget.AppCompatTextView
        android:layout_width="@dimen/dimen_105"
        android:layout_height="@dimen/dimen_32"
        android:maxLines="1"
        android:textSize="@dimen/dimen_sp_12"
        android:textColor="@color/button_r_b_font_color" 
        app:autoSizeTextType="uniform" // 設定TextView大小設定樣式為支援改變(none時為不支援改變)
        app:autoSizeStepGranularity="@dimen/lib_search_dimen_sp_1"   // 每次改變的尺寸階梯
        app:autoSizeMinTextSize="@dimen/lib_search_dimen_sp_8" 
        app:autoSizeMaxTextSize="@dimen/lib_search_dimen_sp_12" /> 

RelativeLayout>

 

這裡採用AppCompatTextView,它是谷歌為了相容老版本而提供的一個新的類,它實現了AutoSizeableTextView介面, 在xml中透過引入app空間下的對應幾個屬性,就可以實現上述根據控制元件寬度來自適應文字的大小的效果。

在程式碼中動態設定

首先,在佈局中宣告控制元件,註意需要宣告的是AppCompatTextView。

 


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dimen_45">

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/txt_price_section_item"
        android:layout_width="@dimen/dimen_105"
        android:layout_height="@dimen/dimen_32"
        android:background="@drawable/red_black_selector_bg"
        android:maxLines="1"
        android:textSize="@dimen/dimen_sp_12"
        android:textColor="@color/button_r_b_font_color" />
RelativeLayout>

 

 

在程式碼中進行改變字號的設定

 

TextViewCompat.setAutoSizeTextTypeWithDefaults(
    textViewTextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM); 
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
    textView, 8, 25, 1, TypedValue.COMPLEX_UNIT_SP);

 

就這兩行程式碼,首先第一個方式是設定TextView字號支援改變大小樣式。

 

第二個方法,根據引數的命名我們也能猜出含義,和上面在xml置頂的幾個屬性是一樣的,這裡我不再複述(最後一個引數是尺寸單位)。

 

這裡需要說明三點,

1、首先為什麼在xml中宣告的控制元件必須是AppCompatTextView我們點選上面的第二個方法的原始碼中看一下:

 

public static void setAutoSizeTextTypeUniformWithConfiguration(
    @NonNull TextView textView, int autoSizeMinTextSize, int autoSizeMaxTextSize, 
    int autoSizeStepGranularity, int unit) throws IllegalArgumentException {
        if (VERSION.SDK_INT >= 27) {
            textView.setAutoSizeTextTypeUniformWithConfiguration(autoSizeMinTextSize, autoSizeMaxTextSize, autoSizeStepGranularity, unit);
        } else if (textView instanceof AutoSizeableTextView) {
            ((AutoSizeableTextView)textView).setAutoSizeTextTypeUniformWithConfiguration(autoSizeMinTextSize, autoSizeMaxTextSize, autoSizeStepGranularity, unit);
        }
    }

看到了吧,其實是為了相容老版本,如果你的專案不針對27以下的版本進行相容,你完全可以直接在xml中宣告TextView控制元件,而且在xml中也可以直接用android宣告的那幾個屬性進行設定,無須再引入app空間下的屬性。

 

而當低於27的時候,這個TextView必須屬於AutoSizeableTextView型別的,而前面已經說過,AppCompatTextView實現了AutoSizeableTextView介面,因此,為了相容老版本,我們在xml宣告的時候需要宣告為AppCompatTextView。

 

小編註:關於第一點,應該是有個前提,如果是繼承自AppCompatActivity,可以直接使用,系統會自動將TextView這個 tag 生成AppCompatTextView實體物件,但是如果是自己做了自定義等操作,一定要繼承AppCompatTextView。

 

之前也推送給相關原理的文章:

Android兩行程式碼實現換膚從appcompat-v7原理出發https://blog.csdn.net/ximsfei/article/details/54604310

 

2、其次,要說到一個特別要註意的事情,那就是控制元件的寬度和高度必須要有具體的值,不能設定為wrap_content。這一點估計也好理解,如果寬高不固定,也就不會有根據寬高改變字號這一問題了。

3、最後,關於一行展示這個屬性,平時我們應該都知道兩種方式。那就是singleLine=”true”,或者maxLines=”1″。看我上面的程式碼,兩種方式我都採用的是maxLines=”1″的方式進行設定,如果用singleLine的話會發現無法顯示預期的效果的。

結語

以上,就是使用android官方提供的方法來實現TextView根據寬高自動改變文字大小的方式!一個小知識點,希望能夠對你有幫助哈!

贊(0)

分享創造快樂