在Flutter中正確處理文本縮放的解決方案
本教程的結(jié)構(gòu)首先介紹最簡(jiǎn)單且最有影響力的解決方案。后面的部分涵蓋了較難實(shí)施且總體影響較小的解決方案,但它們對(duì)于解決特定情況很有用。
限制文本縮放的可能范圍
您可以為 MaterialApp 設(shè)置最小和最大縮放系數(shù),這將確保所有文本在指定范圍內(nèi)縮放。更小的界限需要更少的努力來保持可讀性和美觀性。不過,邊界的選擇應(yīng)取決于目標(biāo)受眾。例如,如果您的應(yīng)用程序是為老年用戶設(shè)計(jì)的,您應(yīng)該考慮使用較寬松的邊界來滿足他們的需求。
MaterialApp( ... builder: (_, child) => MediaQuery( data: MediaQuery.of(context).copyWith( textScaler: MediaQuery.of(context) .textScaler .clamp(minScaleFactor: 0.8, maxScaleFactor: 1.6), ), child: child!, ), );
不要對(duì)包含文本的元素使用固定高度
看一下這段代碼:
//不要這樣做 SizedBox( height: 100, child: Card( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Title", style: TextStyle(fontSize: 30), maxLines: 1), Text("Subtitle", maxLines: 1), ], ), ), ), ),
可能會(huì)出現(xiàn)什么問題?
正如您可能已經(jīng)猜到的,增加文本大小可能會(huì)導(dǎo)致 SizedBox 的內(nèi)容占用過多空間。
更好的解決方案是根據(jù)內(nèi)容高度和填充來設(shè)置項(xiàng)目的高度。此外,您可以使用 ConstrainedBox
設(shè)置最小高度。
ConstrainedBox( constraints: const BoxConstraints(minHeight: 100), child: const Card( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Title", style: TextStyle(fontSize: 30), maxLines: 1), Text("Subtitle", maxLines: 1), ], ), ), ), ),
因此,在 100% 比例下,我們得到了一個(gè)相同的布局,而在 160% 比例下,我們得到了一個(gè)有效的布局。
這同樣適用于 ListView,如果您使用 itemExtent
,請(qǐng)考慮使用字體比例計(jì)算或提供一個(gè) prototypeItem
。
讓我們繼續(xù),想象一下這樣的布局:
項(xiàng)目 A 來自上一個(gè)示例。項(xiàng)目 B 有一些填充,應(yīng)該也能處理增加的文本縮放。屏幕底部有足夠的空間。那么,可能會(huì)出什么問題呢?
不要忘記屏幕較小的手機(jī)。此外,當(dāng)語言發(fā)生變化時(shí),文本長(zhǎng)度也會(huì)發(fā)生變化。
確保內(nèi)容可滾動(dòng)
首先,我們應(yīng)該消除任何溢出,以確保我們的用戶可以訪問所有內(nèi)容。添加一個(gè)簡(jiǎn)單的 SingleChildScrollView
將解決這個(gè)問題。
考慮對(duì)邊距和填充使用自適應(yīng)值
這可能是一個(gè)有爭(zhēng)議的方法,但想象一下您自己是一個(gè)需要使用更大字體的用戶。您希望看到大量未使用的空間還是清楚地閱讀文本?
讓我們使用取決于邏輯像素?cái)?shù)的值來顯示文本。您可以將 smallScreenThreshold
調(diào)整為任何對(duì)您的應(yīng)用程序最合理的值。
class Dimens { static const smallScreenThreshold = 300; static bool isSmallWidth(BuildContext context) { return MediaQuery.of(context).size.width / MediaQuery.textScalerOf(context).scale(1) < smallScreenThreshold; } static double small(BuildContext context) => isSmallWidth(context) ? 4 : 8; static double medium(BuildContext context) => isSmallWidth(context) ? 8 : 16; static double large(BuildContext context) => isSmallWidth(context) ? 16 : 32; }
請(qǐng)注意,如果您想遵循人機(jī)界面指南和 Material Design,這些值應(yīng)能被 4 整除。
基于這些 Dimens
我們可以為插圖創(chuàng)建一個(gè)類:
class Insets { static EdgeInsets small(BuildContext context) => EdgeInsets.all(Dimens.small(context)); static EdgeInsets medium(BuildContext context) => EdgeInsets.all(Dimens.medium(context)); static EdgeInsets large(BuildContext context) => EdgeInsets.all(Dimens.large(context)); }
在代碼中我們將其替換為:
//padding: const EdgeInsets.all(16), padding: Insets.medium(context), //SizedBox(height: 16), SizedBox(height: Dimens.medium(context)),
結(jié)果,我們贏得了更多的空間來在屏幕上繪制文本:
限制標(biāo)題文字大小的擴(kuò)展范圍
增加字體比例的主要目的是使視力下降的人能夠閱讀內(nèi)容。但是,應(yīng)用程序的某些部分(例如標(biāo)題)由于字體較大,可能已經(jīng)可以訪問。為了解決這個(gè)問題,我們可以限制文本可以放大的程度。實(shí)現(xiàn)此目的的一種方法是為標(biāo)題創(chuàng)建自定義小部件:
class TitleText extends StatelessWidget { final String text; final TextStyle style; const TitleText(this.text, {required this.style, super.key}); static const double maxRealFontSize = 30; @override Widget build(BuildContext context) { if (MediaQuery.textScalerOf(context).scale(style.fontSize!) > maxRealFontSize) { return Text( text, style: style.copyWith( fontSize: maxRealFontSize / MediaQuery.textScalerOf(context).scale(1), ), ); } return Text(text, style: style); } }
通過這樣做,我們可以在不失去可讀性的情況下贏得更多空間。您可以將該 maxRealFontSize
更改為更適合您的應(yīng)用的任何值。
指定最大行數(shù)和文本溢出
不要忘記,某些文本在正常文本比例的大屏幕上可能看起來不錯(cuò),但在某些其他條件下可能會(huì)占用更多的垂直空間,但您并不總是需要顯示其完整內(nèi)容,例如字幕。只需將 maxLines
值添加到文本小部件即可。
使用字符串的替代版本
但并不總是能夠以仍然包含有用信息的方式縮短字符串。此外,不同語言的詞序也不同。英語中的第一個(gè)單詞可能位于另一種語言的句子末尾。讓我們考慮這個(gè)國(guó)際化 (i18n) 字符串的示例:
"tasksDone": { "one": "You have done $completed of $n tasks", "other": "You have done $completed of $n tasks" }, "tasksDoneShort": { "one": "$completed/$n tasks done", "other": "$completed/$n tasks done" },
最有意義的部分是顯示數(shù)字的部分。在較短的版本中,我們把它放在開頭,使整個(gè)字符串更短。在代碼中,你可以這樣使用它:
Text( Dimens.isSmallWidth(context) ? t.tasksDoneShort(n: 10, completed: 5) : t.tasksDone(n: 10, completed: 5), maxLines: 1, )
正如您在屏幕截圖中看到的,縮短的版本有助于顯示所需的信息。
以上就是在Flutter中正確處理文本縮放的解決方案的詳細(xì)內(nèi)容,更多關(guān)于Flutter處理文本縮放的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Kotlin利用Regex如何構(gòu)建正則表達(dá)式詳解
正則表達(dá)式,又稱規(guī)則表達(dá)式。下面這篇文章主要給大家介紹了關(guān)于Kotlin利用Regex構(gòu)建正則表達(dá)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-12-12Android?實(shí)現(xiàn)自定義圓形進(jìn)度條的三種常用方法
這篇文章主要介紹了Android?實(shí)現(xiàn)自定義圓形進(jìn)度條的三種常用方法的相關(guān)資料,需要的朋友可以參考下2023-03-03Android UI實(shí)現(xiàn)底部切換標(biāo)簽fragment
這篇文章主要為大家詳細(xì)介紹了Android UI實(shí)現(xiàn)底部切換標(biāo)簽的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12簡(jiǎn)單實(shí)現(xiàn)Android文件上傳
這篇文章主要為大家詳細(xì)介紹了如何簡(jiǎn)單實(shí)現(xiàn)Android文件上傳的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Android編程實(shí)現(xiàn)調(diào)用相冊(cè)、相機(jī)及拍照后直接裁剪的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)調(diào)用相冊(cè)、相機(jī)及拍照后直接裁剪的方法,涉及Android拍照及圖形處理相關(guān)操作技巧,需要的朋友可以參考下2017-02-02Android使用AlertDialog實(shí)現(xiàn)彈出菜單的詳細(xì)過程
在Android經(jīng)常會(huì)用到AlertDialog,下面這篇文章主要給大家介紹了關(guān)于Android使用AlertDialog實(shí)現(xiàn)彈出菜單的詳細(xì)過程,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04