Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Textの構造を理解する/Understanding the Structure of Text
Search
Kakeru Nakabachi
November 29, 2021
Programming
2.8k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Textの構造を理解する/Understanding the Structure of Text
Kakeru Nakabachi
November 29, 2021
More Decks by Kakeru Nakabachi
See All by Kakeru Nakabachi
Flutterアプリで可用性を向上させたFeatureFlagの運用戦略とその方法
b4tchkn
0
2k
Inside Flutter Text
b4tchkn
1
310
Flutterアプリのセキュリティ対策を考えてみる
b4tchkn
6
8.3k
チームで採用しているriverpodを使ったFlutterのアーキテクチャとriverpod v1.0.0
b4tchkn
6
5k
Other Decks in Programming
See All in Programming
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
520
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
180
高専キャリア LT 発表内容
crysta1221
6
5.6k
ALB ログから Trace を気合で繋げる技術
fohte
7
880
Family mrubyの進捗
kishima
1
110
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
660
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
520
業務時間外もAIに働いてもらう話
colorful12
3
10k
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
330
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
XHTMLが残したもの
yosuke_furukawa
PRO
2
640
Foundry Localでエージェント開発
seosoft
0
160
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Side Projects
sachag
456
43k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
680
Facilitating Awesome Meetings
lara
57
7.1k
How to Ace a Technical Interview
jacobian
281
24k
30 Presentation Tips
portentint
PRO
1
390
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
980
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.8k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Transcript
Textの構造を理解する Flutter Kaigi 2021 November 29-30, 2021
Kakeru Nakabachi - batch CyberAgent, Inc 株式会社WinTicketでモバイルアプリをFlutterでリ プレイス中 About me
2
本セッションのゴール Textの構造を理解して実装できるようになる💪💪 3
アジェンダ • Text • Textの構造 • AndroidとiOSでTextを描画したときの問題について • チームで対応した問題の対処法 •
まとめ 4
Text 5
Text 文字を表示するためのWidget • プロパティたち ◦ maxLines ◦ overflow ◦ strutStyle
◦ style ◦ textAlign ◦ textHeightBehavior ◦ ... https://api.flutter.dev/flutter/widgets/Text-class.html 6
Text 文字を表示するためのWidget • プロパティたち ◦ maxLines ◦ overflow ◦ strutStyle
◦ style ◦ textAlign ◦ textHeightBehavior ◦ ... https://api.flutter.dev/flutter/widgets/Text-class.html debugLabel fontFamily fontFamilyFallback fontSize fontStyle fontWeight forceStrutheight hashCode height leading leadingDistribution 7 TextStyleのプロパティ
Text 8 https://api.flutter.dev/flutter/painting/TextStyle-class.html
Text 9 https://api.flutter.dev/flutter/painting/TextStyle-class.html
Text 文字を表示するためのWidget • maxLines • overflow • strutStyle • style
• textAlign • textHeightBehavior • ... https://api.flutter.dev/flutter/widgets/Text-class.html 10
Text 文字を表示するためのWidget • maxLines • overflow • strutStyle • style
• textAlign • textHeightBehavior • ... https://api.flutter.dev/flutter/widgets/Text-class.html 11
Text 文字を表示するためのWidget • maxLines • overflow • strutStyle • style
• textAlign • textHeightBehavior • ... https://api.flutter.dev/flutter/widgets/Text-class.html 12
Textの構造 13
Textの構造 このようなTextを表示した場合、どのような構造でTextが構築されて表示されて いるかをみていく Flutterのvisual debuggingツールを有効化 https://flutter.dev/docs/testing/debugging#visual-debugging https://docs.flutter.dev/development/tools/devtools/inspector 14
Textの構造 実行結果 Android https://api.flutter.dev/flutter/painting/TextStyle-cl ass.html Textが確保している領域 15
Textの構造 実行結果 Android https://api.flutter.dev/flutter/painting/TextStyle-cl ass.html Textのbaseline 16
それぞれの線の意味 baseline ascent: baselineから上部までの高さ descent: baselineから下部までの高さ leading: ある行の下端から次の行の上端までの高さ、TextStyle.height * TextStyle.fontSize
- TextStyle.fontSize これらを意識してTextをつくっていく。今回は以下の3つにフォーカスする height、leadingDistribution、textHeightBehavior Textの構造 AaBbGgJj 17
Textの構造 • height 行の高さをフォントサイズの倍数で調整で きる nullと1.0は別の意味 18 https://api.flutter.dev/flutter/painting/TextStyle-class.html
Textの構造 • leadingDistribution leadingを上下にどのように配置するかを決める。 asent descent Top leading Bottom leading
19
Textの構造 • leadingDistribution TextLeadingDistribution.proportionalと.evenがある leadingを上下にどのように配置するかを決める。nullの場合は TextLeadingDistribution.proportionalと同じ挙動 20
Textの構造 • leadingDistribution leadingを上下にどのように配置するかを決める。 TextLeadingDistribution.evenにした場合はascentとdescentから上下に等 しくleadingが設定される 21
Textの構造 • textHeightBehavior applyHeightToFirstAscentとapplyHeightToLastDescentのbool値を設定す ることでTextの上下のleadingを除くことができる デフォルトはtrueでleadingあり falseを設定してleadingを除いた場合、textHeightBehaviorは効かなくなる 22
Textの構造 • heightとleadingDistributionとtextHeightBehavior Configuration 1 fontSizeとheight以外はすべてデフォル ト設定 leadingDistributionは TextLeadingDistribution.proportional 23
Textの構造 • heightとleadingDistributionとtextHeightBehavior Configuration 2 Configuration 1に TextHeightBehavior.applyHeightToFir stAscentをfalseに設定 24
Textの構造 • heightとleadingDistributionとtextHeightBehavior Configuration 3 leadingDistributionを TextLeadingDistribution.evenに設定 25
Textの構造 • heightとleadingDistributionとtextHeightBehavior Configuration 4 Configuration 3の設定に TextHeightBehavior.applyHeightToLa stDescentにfalseを追加で設定したとき 26
Textの構造 • 複数行の場合 27
Textの構造 • 複数行の場合 height: 2.5を追加 28
Textの構造 • 複数行の場合 TextHeightBehavior.applyHeightToFirstAscent: falseを追加 29
Textの構造 • 複数行の場合 TextHeightBehavior.applyHeightToLastDescent: falseを追加 30
Textの構造 • 複数行の場合 leadingDistributionにTextLeadingDistribution.proportionalの設定 31
Textの構造 • 複数行の場合 leadingDistributionにTextLeadingDistribution.evenの設定 32
Textの構造 • 複数行の場合 TextStyleのleadingDistributionとTextHeightBehaviorの leadingDistribution TextStyle側が優先されて使われる 33
Textの構造 • 複数行の場合 TextStyleのleadingDistributionとTextHeightBehaviorの leadingDistribution TextStyle側が優先されて使われる 34
AndroidとiOSでTextを描画したときの 問題について 35
問題1:OSごとにTextのサイズが違う • 実はAndroidとiOSでは同じフォントサイズなどstyleの設定でもTextの高さ が異なる ➢ 高さ固定のWidgetの中にTextなど配置した場合に、片方のOSでは収ま るけど、もう一方では収まらなかったり、OS間で異なったデザインにな る 両OSのデザインがある場合は大丈夫 弊チームではiOSのデザインしかなくどのように対応するか考える必要があった
36
問題1:OSごとにTextのサイズが違う 実はiOSとAndroidでは同じフォントサイズなどの設定でもTextの高さが異なる Android 37
問題1:OSごとにTextのサイズが違う 実はiOSとAndroidでは同じフォントサイズなどの設定でもTextの高さが異なる iOS 38
問題1:OSごとにTextのサイズが違う なぜ起こる? OSによってleadingの高さが違う、、? →TextHeightBehaviorを設定して上下のleadingをなくしたらどうなるか AaBbGgJj 39
問題1:OSごとにTextのサイズが違う TextHeightBehaviorを設定してみる Android 40
問題1:OSごとにTextのサイズが違う TextHeightBehaviorを設定してみる iOS 41
問題1:OSごとにTextのサイズが違う AndroidとiOSでTextHeightBehaviorの設定の挙動が違いそう?バグ、、? Android iOS 42
問題1:OSごとにTextのサイズが違う 結論:fontFamilyを指定しなかった場合、OSごとに読み込まれるフォントが異 なり、ascentとdescentが異なるため Android Pixel 4a 和文フォント:Noto Sans Japanese? 欧文フォント:Roboto
iOS iPhone 12 Pro 和文フォント:ヒラギノ角ゴシック 欧文フォント:San Francisco Pro 43
問題1:OSごとにTextのサイズが違う TextStyle.backgroundColorを設定して、Textの中でフォントが確保している領域 を見てみる。和文フォントで大きく確保する領域に違いがある Android iOS 44
問題1:OSごとにTextのサイズが違う TextStyle.backgroundColorを設定して、Textの中でフォントが確保している領域 を見てみる。和文フォントで大きく確保する領域に違いがある Android iOS Androidのフォントが確保している領域が iOSより広い 45
問題2:Androidだと文字が下寄りに見える https://github.com/flutter/flutter/issues/79931 46
問題2:Androidだと文字が下寄りに見える Android iOS 24.0 32.0 fontSize 47
問題2:Androidだと文字が下寄りに見える Androidの方がフォントがデフォルトで確保している ascentとdescentが大きく、ascentの方が大きいので 下寄りに見える Android iOS 48
問題2:Androidだと文字が下寄りに見える Androidの方がフォントがデフォルトで確保しているascentと descentが大きく、ascentの方が大きいので下寄りに 見える Android iOS 49
チームで対応した問題の対処法 50
チームで対応した問題の対処法 ▪ 一般的な対処法と思われるもの • AndroidとiOSで共通のascentとdescentが小さいフォントを使う • AndroidだけiOSのシステムフォントのようなascentとdescentが小さい フォントを使う 51
チームで対応した問題の対処法 ▪ 一般的な対処法と思われるもの • AndroidとiOSで共通のascentとdescentが小さいフォントを使う • AndroidだけiOSのシステムフォントのようなascentとdescentが小さい フォントを使う ➢ 弊チームでの対応はこれ
52
チームで対応した問題の対処法 ▪ AndroidでiOSのシステムフォントのようなascentとdescentが小さいフォン トを使うためには Androidで角ゴシックを使えば両プラットフォームで全く同じTextにすることが できるが、、、 ➢ Androidユーザは普段と違うフォントを目にすることになって違和感か もしれない ➢
ライセンス問題( https://developer.apple.com/forums/thread/89094 ) 53
チームで対応した問題の対処法 ▪ Android用にascentとdescentが小さいフォントを用意する必要がある ➢ NotoSans CJKを使用 CJK = Chinese Japanese
Korean 今はJapaneseのみが入ったファイルサイズの小さいNotoSansJapaneseがあ る https://fonts.google.com/noto/specimen/Noto+Sans+JP 54
チームで対応した問題の対処法 ▪ Android用にascentとdescentが小さいフォントを用意する必要がある NotoSans CJKのままでは、中国語や韓国語など使わないフォントも多いので、サ ブセット化してフォントファイルサイズを削減 .otf → .woff →
.ttf → サブセット化(JIS第1水準+JIS第2水準+その他) NotoSans CJK RegularとNotoSans CJK Boldを用意 サブセット化前 サブセット化後 34MB 3MB 55
チームで対応した問題の対処法 ▪ Android用にascentとdescentが小さいフォントを用意する必要がある コンバートする段階でascentとdescentが除かれたフォントができあがることを 利用してiOSのフォントのような扱いをしている https://github.com/minoryorg/Noto-Sans-CJK-JP ライセンス的には商用利用可、改変可 https://fonts.google.com/noto/use#bundle-noto-fonts-with-your-native-app https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 56
チームで対応した問題の対処法 ▪ Android用にascentとdescentが小さいフォントを用意する必要がある フォントの指定方法 なにも指定がない場合、OSのデフォルトのシステムフォントが使われる 57 ← 最初に読み込もうとするフォントを指定 ← fontFamilyで対応できなかった文字を描画す
るためのフォントを指定
チームで対応した問題の対処法 ▪ Android用にascentとdescentが小さいフォントを用意する必要がある フォントの指定方法 用意したフォントは日本語表示用に、英語はシステムフォントでデフォルトで選 択されるRobotoを使いたい fontFamilyに何も指定しない場合→Robotoが使われる 日本語を表示しようとしたとき、Robotoだけでは対応できずfontFamilyFallback に設定されているフォントを読み込もうとする なので、今回は用意したフォントをfontFamilyFallbackに設定
58
チームで対応した問題の対処法 ▪ ボタンなどの垂直方向の中央に文字が表示されるようにleadingの調整 ascentとdescentが小さいフォントを使うことにより、 デフォルトのleadingが効 くようになり、文字が厳密にはまだ中心に配置されていない TextStyle.leadingDistributionにTextLeadingDistribution.evenを設定して、上 下に等しくleadingを配置して文字が垂直方向に中心に配置されるようにする 59 フォント変更前
フォント変更後
まとめ • Textは様々な要素で構成されている • AndroidとiOSではフォントを指定しない場合、読み込むシステムフォントが それぞれ違うため、全く同じ見た目のTextを描画しない ◦ 高さが違う ◦ 文字が下よりに見える
• 対応方法の1つにAndroidのときはデフォルトでasecntとdescentが大きいシ ステムフォントが使われるため、それらが小さいフォントを指定してiOSの 挙動に近づける • TextStyle.leadingDistributionにTextLeadingDistribution.evenを設定して 上下のleadingを均等に配分して文字を中央にする 60
参考 • https://flutter.dev/docs/testing/debugging#visual-debugging • https://flutter.dev/docs/development/tools/devtools/inspector • https://stackoverflow.com/questions/56799068/what-is-the-strutstyl e-in-the-flutter-text-widget • https://api.flutter.dev/flutter/painting/TextStyle-class.html
• https://github.com/flutter/flutter/issues/79931 • https://fonts.google.com/noto/use#bundle-noto-fonts-with-your-nativ e-app • https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL • https://github.com/minoryorg/Noto-Sans-CJK-JP 61
Thank you 62