Android TextView autosizing 自動調整大小

遇見問題:當一個控件顯示的文本有點長的時候,可能在屏幕小的設備上就會變得顯示不完整,特別是那種不允許文本省略的按鈕。

最近又有這個需求,並且發現官方已經支持這個自適應大小的TextView了。

Android 8.0(API級別26)允許您指示TextView文本大小自動擴展或收縮,以根據其TextView特徵和邊界填充其佈局。此設置可以更輕鬆地使用動態內容優化不同屏幕上的文本大小。


本身要有這個新特性的話,在Android 8.0 才有效,對於開發者而言,就顯得有點雞肋了,可能還需要一段時間才能普及使用。不過呢,在Android Support v26 之上,也對Autosizing 提供了兼容支持,最低可以支持到Android Level 14。

Autosizing 允許TextView 根據其內部文本的顯示大小,動態的調整其TextSize 屬性值得大小,通過此設置,開發者可以很輕鬆的在具有動態內容的情況下,對不同的屏幕中,文本大小進行優化。

Autosizing 的核心設計思想,就是為了讓文本盡可能的完全顯示在既定大小的TextView 中,哪怕是修改它的文字大小。

使用方法:

對於Android 8.0 Api:

  1. 動態編碼是直接操作的TextView 上的方法。
  2. layout-xml佈局屬性,是使用的android:命名空間下的屬性進行設置。
<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:autoSizeTextType="uniform" />

低於Android 8.0 的設備:

  1. 動態編碼,使用TextViewCompat 中提供的方法。
  2. layout-xml佈局屬性,需要使用app:命名空間下的屬性,記住要添加xmlns:app="http://schemas.android.com/apk/res-auto"這個命名空間。
<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    app:autoSizeTextType="uniform" />

Autosizing的基礎

  1. 有開關限制,只在我們需要的TextView 上,才開啟這個特性。
  2. 允許設置邊界值,最大縮放和最小縮放。
  3. 能配置每次縮放的最小尺寸,例如:10sp 為粒度進行縮放。
  4. 能預設一些縮放的定位尺寸,例如預設一組尺寸,只讓它在這個範圍內的值中選一個。
  5. 方便的Api ,可以通過layout-xml 屬性和動態編碼的方式操作它。

Autosizing 開關

Autosizing 是直接作用在TextView 上的,對於它的開啟和關閉,我們可以直接操作autoSizeTextType 屬性。

對於動態編碼,可以使用TextViewCompat的setAutoSizeTextTypeWithDefaults()方法,下面是它的方法簽名。
參數中的textView是我們要操作的TextView,而autoSizeTextType,就是我們關心的Autosizing的開關屬性了,它接受兩個參數。
  • AUTO_SIZE_TEXT_TYPE_NONE:關閉自動調整功能。
  • AUTO_SIZE_TEXT_TYPE_UNIFORM:開啟統一縮放碎片軸和垂直軸。

操作Autosizing 的粒度

粒度的含義其實就是Autosizing 每次變動的最小單位,當然在設置粒度的同時,你還需要為其設置一個縮放的範圍,最大值和最小值。

這樣,在Autosizing 生效的時候,它會在這個範圍內,按照我們設定的粒度,去動態的調整文字的大小。

想要操作這些屬性,動態編碼的方式你需要調用TextViewCompat的setAutoSizeTextTypeUniformWithConfiguration()方法。
參數很直觀,沒什麼好解釋的,一個最小值、一個最大值、變動的粒度、前面設置的尺寸的單位。

我們可以通過unit 參數,通過TypedValue 來設置前面設置的幾個參數的單位,例如:sp 、dp、px,都可以。

預設尺寸範圍

如果你按上一小節,介紹的屬性,設置了Autosizing 的粒度,就可以在這個範圍內,根據我們設置的粒度進行縮放。通常,使用粒度來控制基本上可以達到我們的要求,但是如果對縮放有更精準的要求,例如:[10.15,40,60,100] 這樣的縮放,使用粒度就達不到我們的要求了。

針對這樣的操作,Autosizing 也提供了對應的屬性來設置,那就是預設尺寸(Preset Size)。

如果想要使用預設尺寸,動態編碼的方式,你需要操作TextViewCompat的setAutoSizeTextTypeUniformWithPresetSizes()方法。
預設尺寸可以接受一個尺寸數組,Autosizing 就會從我們設定的尺寸數組中,取一個尺寸進行設置。同時你可以為這些尺寸設置一個統一的尺寸單位。

如果想要在layout-xml使用屬性的形式使用預設尺寸,你首先需要一個array的資源,然後通過autoSizePresetSizes屬性進行設置即可。

array 資源的格式:
<resources>
  <array name="autosize_text_sizes">
    <item>10sp</item>
    <item>12sp</item>
    <item>20sp</item>
    <item>40sp</item>
    <item>100sp</item>
  </array>
</resources>

其他問題

到這裡,我們就把Autosizing 的基本使用細節,都講解清楚了。但是,依然還有一些概念,是在文檔上沒有反應出來的,下面我們就來講講這些“經驗”。
  • TextView 必須限定尺寸
  • Autosizing 只能作用在顯示文本的控件(TextView)中
  • 預設尺寸不一定都命中
  • 和singleLine 衝突
筆記!!

留言

這個網誌中的熱門文章

Android - 使用 adb 安装apk

Kotlin - 實現Android中的Parcelable