The native Android Toast has only two options for message duration (SHORT or LONG). Here we define a custom Toast, which uses a custom XML layout, and whose display duration is calculated to be proportional to the length of the Toast message (measured in number of characters).
- the custom XML Layout is inflated with a inflater service, and assigned to the basic toast "view" member
- a basic toast is displayed with the SHORT duration, but is actually shown multiple times in a countdown loop until the predefined display time has ended
class CustomToast {
companion object {
// NOTE: we must create a new custom toast for each tick
public fun show(context: Context?, text: String) {
context?.runOnUiThread {
val durationinMillisecondsPerCharacter: Long = 50
val duration: Long = text.length * durationinMillisecondsPerCharacter
val timer = object : CountDownTimer(duration, 1000) {
override fun onFinish() {
setCustomLayoutView(context, text)?.show()
}
override fun onTick(p0: Long) {
setCustomLayoutView(context, text)?.show()
}
}
timer.start()
}
}
private fun setCustomLayoutView(context: Context, text: String) : Toast? {
val toast = Toast(context)
toast.setDuration(Toast.LENGTH_SHORT)
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.layout_custom_toast, null)
view.findViewById<TextView>(R.id.custom_toast_text)?.let{
it.setText(text)
}
toast.view = view
return toast
}
}
}