I had an specific case which was a single line EditText, so I'm posting my solution just in case to be helpful to someone...
private val initialTextSize: Float by lazy {
resources.getDimensionPixelSize(R.dimen.default_text_size).toFloat()
}
private fun updateTextSize(s: CharSequence) {
// Auto resizing text
val editWidth = myEditText.width
if (editWidth > 0) { // when the screen is opened, the width is zero
var textWidth = myEditText.paint.measureText(s, 0, s.length)
if (textWidth > editWidth) {
var fontSize = initialTextSize
while (textWidth > editWidth && fontSize > 12) { // minFontSize=12
fontSize -= 1
myEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
textWidth = myEditText.paint.measureText(s, 0, s.length)
}
// As long the text grows, the font size decreases,
// so here I'm increasing it to set the correct text s
} else {
var fontSize = myEditText.textSize
while (textWidth <= editWidth && fontSize < initialTextSize) {
fontSize = min(fontSize + 1, initialTextSize)
myEditText.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize)
textWidth = myEditText.paint.measureText(s, 0, s.length)
}
}
}
}
Then you must call this function from a TextWatcher attached to the EditText.
private fun createTextWatcher() = object : SimpleTextWatcher() {
override fun beforeTextChanged(s: CharSequence?,
start: Int, count: Int, after: Int
) {
super.beforeTextChanged(s, start, count, after)
s?.let { updateTextSize(it) }
}
override fun onTextChanged(
s: CharSequence?,
start: Int,
before: Int,
count: Int
) {
// Do nothing
}
override fun afterTextChanged(s: Editable?) {
super.afterTextChanged(s)
s?.let { updateTextSize(it) }
}
}