TextViewの文字列を段階的に表示する方法
文字列を時間差で徐々にアニメーション表示する方法
ヒーラー
クイズ番組の問題文のアニメーションのように、少しずつテキストを表示するようにしたい
やりたいこと
タイプライターのようにテキストを1文字ずつ徐々に表示します。
テキストに動きを付けることで、伝えたいメッセージを強調したり注目を得ることができます。
以下はクイズの問題文を表示する際に、問題を読み上げているような雰囲気を出す具体例です。
文字列を一発で表示するよりもクイズの臨場感が表現することができます。
対処方法
Handlerを使用して一定時間の遅延処理をさせながら、テキスト表示部分に対して、1文字ずつ段階的に表示したい文字数を増やしていきながら表示する対応です。
TextViewを継承したTypewriterTextViewを作成しました。
具体的には以下のようなコードです。
class TypewriterTextView : AppCompatTextView {
private var typewriterText: CharSequence = ""
private var index: Int = 0
private var canType: Boolean = true
private var delay: Long = 50
private val mainHandler: Handler = Handler(Looper.getMainLooper())
private val typewriter: Runnable = object : Runnable {
override fun run() {
text = typewriterText.subSequence(0, index++)
if (index <= typewriterText.length && canType) {
mainHandler.postDelayed(this, delay)
}
}
}
fun setDelay(millis: Long) {
delay = millis
}
fun animateText(text: CharSequence) {
typewriterText = text
index = 0
setText("")
mainHandler.removeCallbacks(typewriter)
mainHandler.postDelayed(typewriter, delay)
}
fun stopAnimation() {
mainHandler.removeCallbacks(typewriter)
}
fun pauseAnimation() {
canType = false
}
fun restartAnimation() {
canType = true
mainHandler.postDelayed(typewriter, delay)
}
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
}
https://github.com/yoshidaipon/TypewriterTextView
使うときは、これだけです。
textView.animateText("表示したいテキスト")
表示速度(間隔)時間のデフォルト0.05秒(50ミリ秒)です。
それぞれ、表示速度(間隔)を変えるためのメソッドや、停止、一時停止、再開のメソッドもあります。
//表示間隔時間の設定(ミリ秒)
fun setDelay(millis: Long) {
delay = millis
}
//停止
fun stopAnimation()
//一時停止
fun pauseAnimation()
//再開
fun restartAnimation()