2022/2からGoogle Play Storeのストア規約に「Android 絵文字ポリシー」が加わり、古い端末でも最新の絵文が表示できるようサポートすることが求められるようになります。
Android 絵文字ポリシー
TextViewを継承しているコンポーネントを使用している部分は、AppCompat(v1.4以上)を用いたり、AppCompatを用いない場合もemoji2ライブラリを使用することでほとんど何もしなくてもorかなり簡単に対応できるよう公式のサポートがあります。
最新の絵文字のサポート
しかし、Canvas#drawText を使用していている部分(例えば画面表示を元にCanvas(とBitmap)を使用してスクリーンショット風の画像ファイルを1から生成しているときや、TextViewを使わずに完全なカスタムViewでonDraw()メソッドでCnavasに直書きしているときなど)は、上記の公式サイトの内容では不十分だと思います。
そのようなシチュエーションでの最新の絵文字のサポートへの対応方法について記述しています。
Before(最新の絵文字のサポート対応前)
// canvas : 描きたい対象のCanvasインスタンス
// 描きたいテキスト
val titleStr = "×××"
val textPaint = Paint().apply {
color = android.graphics.Color.BLACK
}
val rect = Rect()
textPaint.getTextBounds(
titleStr,
0,
titleStr.length,
rect
)
// 描きたいテキストの描いた時の横幅を取得
val textWidth = textPaint.measureText(titleStr)
// canvas の上寄せ・横方向中央寄せに描く
val textMarginTop = 8f // テキストの上方向のマージン
canvas.drawText(
titleStr,
(canvas.width - textWidth) / 2,
rect.height().toFloat() + textMarginTop,
textPaint
)
After(最新の絵文字のサポート対応後)
- app/build.gradle
dependenciesにandroidx.emoji2:emoji2
を追加します。
(略)
dependencies {
(略)
def emojiVersion = "1.0.1"
implementation "androidx.emoji2:emoji2:$emojiVersion"
}
- kotlinコード
// canvas : 描きたい対象のCanvasインスタンス
val titleStr = "×××"
// そのまま canvas.drawTextとすると、端末のデフォルトの絵文字が使われてしまう。
// 最新の絵文字を表示しようとすると豆腐になった、となる可能性があるのでEmojiCompatを使用するようにする。
val emoji = EmojiCompat.get().process(titleStr)
val textPaint = Paint().apply {
color = android.graphics.Color.BLACK
}
// StaticLayout+EmojiCompatに作ってもらったCharSequenceを使用すると、Canvasに対しても最新の絵文字を描ける。
val layout = StaticLayout.Builder
.obtain(
emoji!!, 0, emoji.length, TextPaint(textPaint),
canvas.width
)
.setAlignment(Layout.Alignment.ALIGN_CENTER) // setAlignment(Layout.Alignment.ALIGN_CENTER)で横方向中央寄せは実現
.build()
// canvas の上寄せ・横方向中央寄せに描く
val textMarginTop = 8f // テキストの上方向のマージン
canvas.save()
// 上寄せで上にマージンを適用するためにCanvasの原点をずらす
canvas.translate(0f, textMarginTop)
layout.draw(canvas)
canvas.restore()