試試 TextView 的新特性 Autosizing 吧!字體大小變化自適應

      網友投稿 1140 2025-03-31

      Android 8.0 已經發布了有一陣子了,如果你有在關注它,你應該會知道它新增了一個對于 TextView 字體大小變動的新特性:Autosizing。

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

      這樣,我們就有了研究的必要了,接下來本文就來講解一下,Autosizing 屬性,你在使用過程中的所有細節。

      一、什么是 Autosizing?

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

      簡單來說,一個 100dp 長度的 TextView ,正常來說只能顯示 10 個 10dp 的文字,而如果它的內容超出了 10 個字,以前的通用做法,是通過屬性設置,讓它在末尾顯示 "…" 。而采用了 Autosizing 這個新特性,它的方案是將字體的尺寸縮小,例如縮小到 8dp,讓 TextView 可以容納下更多的文字,顯示完全。而這一切,使用 Autosizing 我們只需要設置一些屬性就可以做到,非常的簡單。

      上面這個 Gif 應該可以很直觀的描述 Autosizing 的特性,而它也反映出,觸發 Autosizing 重新計算 TextSize 的時機有兩個:

      TextView 中的文字增多到無法容納的地步。

      TextView 本身的尺寸被放大或縮小了。

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

      二、使用 Autosizing

      2.1 Autosizing 不同使用方式

      前面也提到,使用 Autosizing 其實是區分使用 Android Api Level 26(8.0) 和 使用 Support Library v26 兩種。它們的使用方式,會略微有點區別。

      下面,我們先來了解一下它們之間的區別。

      Autosizing 的帶來的效果很簡單,就是根據文字的內容,動態修改 TextSize ,而想要使用它,可以通過動態編碼和靜態的 layout-xml 布局屬性的方式使用。

      對于 Android 8.0 Api:

      動態編碼是直接操作的 TextView 上的方法。

      layout-xml 布局屬性,是使用的 android: 命名空間下的屬性進行設置。

      android:layout_width="match_parent"

      android:layout_height="200dp"

      android:autoSizeTextType="uniform" />

      復制代碼

      而在低于 Android 8.0 的設備上,只能使用 Support v26 了。此時,TextView 上并沒有對應的方法能讓我們調用,所以我們需要繞一層。

      動態編碼,使用 TextViewCompat 中提供的方法。

      layout-xml 布局屬性,需要使用 app: 命名空間下的屬性,記住要添加 xmlns:app="http://schemas.android.com/apk/res-auto" 這個命名空間。

      xmlns:android="http://schemas.android.com/apk/res/android"

      xmlns:app="http://schemas.android.com/apk/res-auto"

      android:layout_width="match_parent"

      android:layout_height="match_parent">

      android:layout_width="match_parent"

      android:layout_height="200dp"

      app:autoSizeTextType="uniform" />

      復制代碼

      使用標準的 8.0 Api 的使用場景,在現階段會非常的少,所以我們這里只是簡單了解一下區別就好了,下面的文章內容會主要以 Support v26 的方式進行講解。

      2.2 Autosizing 基礎

      到這里,你應該對 Autosizing 有了基本的概念,知道它是干什么的。

      那么,如果讓你來設計一個這樣的功能,你會想要做到哪些點?

      有開關限制,只在我們需要的 TextView 上,才開啟這個特性。

      允許設置邊界值,最大縮放和最小縮放。

      能配置每次縮放的最小尺寸,例如:10sp 為粒度進行縮放。

      能預設一些縮放的定位尺寸,例如預設一組尺寸,只讓它在這個范圍內的值中選一個。

      方便的 Api ,可以通過 layout-xml 屬性和動態編碼的方式操作它。

      嗯,功能上大概就是這些了,已經滿足我的需要了。

      如果你看了 Autosizing 的文檔,你會發現,它全部都支持!

      Autosizing TextView Doc:

      https://developer.android.google.cn/guide/topics/ui/look-and-feel/autosizing-textview.html

      2.3 Autosizing 開關

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

      對于動態編碼,可以使用 TextViewCompat 的 setAutoSizeTextTypeWithDefaults() 方法,下面是它的方法簽名。

      參數中的 textView 是我們要操作的 TextView,而 autoSizeTextType,就是我們關心的 Autosizing 的開關屬性了,它接受兩個參數。

      AUTO_SIZE_TEXT_TYPE_NONE:關閉自動調整功能。

      AUTO_SIZE_TEXT_TYPE_UNIFORM:開啟統一縮放碎片軸和垂直軸。

      我們也可以通過 layout-xml 屬性的方式,來設置 autoSizeTextType,因為是 Support ,所以使用的 app: 命名空間下的屬性。

      xmlns:android="http://schemas.android.com/apk/res/android"

      xmlns:app="http://schemas.android.com/apk/res-auto"

      android:layout_width="match_parent"

      android:layout_height="match_parent">

      android:layout_width="match_parent"

      android:layout_height="200dp"

      app:autoSizeTextType="uniform" />

      復制代碼

      app:autoSizeTextType 同樣接收兩個參數 uniform 和 none,含義和上面代碼中設置的參數一致。

      2.4 操作 Autosizing 的粒度

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

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

      想要操作這些屬性,動態編碼的方式你需要調用 TextViewCompat 的 setAutoSizeTextTypeUniformWithConfiguration() 方法。

      參數很直觀,沒什么好解釋的,一個最小值、一個最大值、變動的粒度、前面設置的尺寸的單位。

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

      這里操作的參數,在 layout-xml 中,都提供了對應的屬性可供我們使用。

      xmlns:android="http://schemas.android.com/apk/res/android"

      xmlns:app="http://schemas.android.com/apk/res-auto"

      android:layout_width="match_parent"

      android:layout_height="match_parent">

      android:layout_width="match_parent"

      android:layout_height="200dp"

      app:autoSizeTextType="uniform"

      app:autoSizeMinTextSize="12sp"

      app:autoSizeMaxTextSize="100sp"

      app:autoSizeStepGranularity="2sp" />

      復制代碼

      下面我們舉兩個例子看看,就清晰了。

      在默認情況下,如果你沒有設置這三個屬性,Autosizing 會根據當前 TextView 控件的大小,估算出一個最大值和最小值,并且將粒度設置為 1sp 。

      可以看到,它設置的尺寸是跳動的,非常的不可控,我們很難知道下一次縮放,會將 文本 尺寸,設置成多大,所以才需要使用 粒度 的概念來限制它縮放的大小。

      例如,現在我們修改上面的例子,將(minSize,maxSize),限制在 (10sp,80sp)之間,粒度(Granularity)設置為 10sp,此時再來看它的效果。

      到這里可以看到,它每次放大或者縮小,粒度都是以 10sp 為基準。

      所以,如果你需要使用 Autosizing ,強烈建議你使用 粒度 來控制它縮放的大小,讓它在可控的范圍內使用。需要注意的是,這里介紹的三個屬性,一定要設置在一個合理的范圍內,否則 TextView 會認為這是一個無效的設置,將它忽略掉。

      2.5 預設尺寸范圍

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

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

      如果想要使用預設尺寸,動態編碼的方式,你需要操作 TextViewCompat 的 setAutosizeTextTypeUniformWithPresetSizes() 方法。

      預設尺寸可以接受一個尺寸數組,Autosizing 就會從我們設定的尺寸數組中,取一個尺寸進行設置。同時你可以為這些尺寸設置一個統一的尺寸單位。

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

      array 資源的格式:

      10sp

      12sp

      20sp

      40sp

      100sp

      復制代碼

      定義好 array 的尺寸資源之后,就可以在 layout-xml 中使用它。

      xmlns:android="http://schemas.android.com/apk/res/android"

      xmlns:app="http://schemas.android.com/apk/res-auto"

      android:layout_width="match_parent"

      android:layout_height="match_parent">

      android:layout_width="match_parent"

      android:layout_height="200dp"

      app:autoSizeTextType="uniform"

      app:autoSizePresetSizes="@array/autosize_text_sizes" />

      試試 TextView 的新特性 Autosizing 吧!字體大小變化自適應

      復制代碼

      預設尺寸非常簡單,這里就不再給運行效果了。

      三、查缺補漏

      到這里,我們就把 Autosizing 的基本使用細節,都講解清楚了。但是,依然還有一些概念,是在文檔上沒有反應出來的,下面我們就來講講這些 “經驗”。

      3.1 TextView 必須限定尺寸

      如果你想要使用 Autosizing,就必須對 TextView 這個控件,限定大小,不能使用 wrap_content 來作為限定符。

      用官方文檔話來說,使用 wrap_content 可能出現不可預料的效果。其實這也非常好理解,如果 TextView 的尺寸不是固定的,那就不存在 TextView 重新計算尺寸的依據了,同比放大 TextView 就可以達到容納文字的效果了。

      我在實際使用過程中會發現,它會阻止放大效果。例如一個 TextView 中使用了 Autosizing,一直增加文本內容,是可以正常縮小的,但是當你刪除文本的時候,它并不會隨之放大文字尺寸。

      但是不確定還有沒有其它的問題,這里建議按照官方文檔的建議來操作,限定 TextView 的尺寸。

      3.2 Autosizing 不能作用在 EditText 中

      雖然通常作用在 TextView 上的新屬性,對于同樣用于顯示文本的控件,例如:Button、EditText 等,都是同樣適用的。

      但是 Autosizing 就是這么特殊,它只對單純只能顯示 文本 的控件有效,例如 Button,而對于 EditText 這種可以輸入 文本 的控件,是無效的。

      這個,你可以在 AppCompatTextViewAutoSizeHelper 這個類的 supportsAutoSizeText() 方法中找到答案,它是一個兼容類,用于向下兼容 Autosizing 特性。

      這里可以看到,只要不是 AppCompatEditText 就返回 true,注釋也說明了這一點。

      暫時沒有想到這樣設計的原因,可能是因為輸入文本的控件,本身長度就是在經常變化的,是一個極端不可控的情況,所以應該為輸入的控件,限定一個固定的尺寸。

      3.3 預設尺寸不一定都命中

      如果想要控制文字的縮放尺寸為限定的范圍內,例如使用 粒度 限定它在一個 10sp 的精度下縮放;或者使用預設尺寸,限定一些尺寸,讓它只能使用我們預定的一些尺寸。

      但是這些,并不是一定的。

      例如,我們使用預設尺寸,預設了一組[10sp,20sp,25sp,40sp],這樣一組尺寸,其中,可能某個尺寸就永遠不會被命中,例如 25sp。

      這是因為,Autosizing 在起作用的時候,會去計算尺寸是否合適,假如到 20sp 之后,再減少文字,這個時候先獲取 25sp ,通過計算發現 25sp 也放不下這些文字,就會直接跳到 40sp 這個尺寸上去。

      所以,并不是我們設定的尺寸,它就是以線性的方式去獲取尺寸。

      3.4 和 singleLine 沖突

      如果你想在 TextView 中,只顯示一行文字,在之前你可以使用 android:singleLine 這個屬性,對其標記。而如果你 同事使用 Autosizing,你會發現 Autosizing 就不再生效,它會在末尾顯示 “…”。

      所幸的是,android:singleLine 已經被標記為廢棄,所以本身我們就不建議使用它,如果你想讓 TextView 只顯示單行文字,可以使用 android:maxLines="1" 屬性,它是可以正常和 Autosizing 兼容的。

      四、使用場景

      Autosizing 說起來非常的簡單,但是它能有哪些適用場景呢?簡單說說我能想到的一些適用場景吧,大家可以開放思維。

      4.1 限定條目的 UI

      這個,其實很常見,例如一些選擇題的 UI,當你有多個需要選擇答案的 UI ,并列的顯示出來。如果它們的文字長度是可變的(通常都是可變的),你除了放大某一行的高度之外,現在還可以使用 Autosizing 來控制它的大小。

      例如最近比較火的沖頂大會類 App,就是一個標準的選擇題的 UI 布局。

      我們可以在答案文字過多的時候,使用 Autosizing 將它縮小,就能正好放在這個既定大小的選項 UI 中。

      4.2 多語言

      Autosizing 在 App 的多語言適配中,也可以大放異彩。

      首先你要考慮到,當你想讓 App 適配多語言的話,一個很嚴重的問題,就是不同的語言,描述同一個詞的時候,長度是不一致的。

      例如中文下簡單的一句:我是 Android 開發者,翻譯成不同的語言,長度是不一致的。

      英語:I am an Android developer

      阿拉伯語:??? ???? ???????

      意大利語:Sono uno sviluppatore Android

      德語:Ich bin ein Android-Entwickler

      法語:Je suis un développeur Android

      在這樣的情況下,我們如果有 Autosizing 就非常的好解決這個問題了。

      Android TextView

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel開發工具在哪里(excel開發工具在哪里找)
      下一篇:怎么查找數據(中國統計年鑒怎么查找數據)
      相關文章
      久久夜色精品国产噜噜噜亚洲AV| 亚洲av永久无码精品网站| 老司机亚洲精品影院| 亚洲午夜爱爱香蕉片| 亚洲国产高清精品线久久| 午夜亚洲国产成人不卡在线| 最新亚洲人成无码网www电影| 亚洲精品自偷自拍无码| 亚洲一卡2卡三卡4卡无卡下载| 亚洲宅男精品一区在线观看| 中文字幕亚洲男人的天堂网络| 亚洲AV综合色区无码二区爱AV| 亚洲一级免费毛片| 色老板亚洲视频免在线观| 亚洲人成图片网站| 亚洲精品国产精品| 精品亚洲福利一区二区| 亚洲成av人在片观看| 亚洲一级特黄大片无码毛片| 亚洲自偷自偷在线制服| 亚洲大尺度无码专区尤物| 亚洲AV无码一区二区乱子伦 | 国产91在线|亚洲| 亚洲乱码在线观看| 亚洲免费网站观看视频| 亚洲av成人一区二区三区观看在线| 亚洲Av无码国产一区二区| yy6080久久亚洲精品| 亚洲精品视频在线观看你懂的| 超清首页国产亚洲丝袜| 亚洲成AV人在线观看天堂无码| 久久久久亚洲av无码专区| 亚洲一区二区三区精品视频| 亚洲天堂2017无码中文| 亚洲av综合日韩| 成人亚洲性情网站WWW在线观看| 日韩va亚洲va欧洲va国产| 亚洲综合视频在线| 2020天堂在线亚洲精品专区| 亚洲A∨精品一区二区三区下载| 亚洲国产午夜福利在线播放|