Skip to content

Instantly share code, notes, and snippets.

@ezamelczyk
Created January 8, 2020 07:52
Show Gist options
  • Save ezamelczyk/2d6acb5cb3a11db151cf8d03b689b3fa to your computer and use it in GitHub Desktop.
Save ezamelczyk/2d6acb5cb3a11db151cf8d03b689b3fa to your computer and use it in GitHub Desktop.
Autosizing EditText kotlin extension.
fun EditText.setAutoSizing() {
initialTextSize = textSize
afterTextChanged { autoSizeText() }
}
private fun EditText.autoSizeText() {
if(text.isEmpty()) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, initialTextSize)
return
}
val length = paint.measureText(text.toString())
paint.getTextBounds(text.toString(), 0, text.length, autoSizeBounds)
val widthSize = textSize * width / length
val heightSize = textSize * height / autoSizeBounds.height()
setTextSize(TypedValue.COMPLEX_UNIT_PX, arrayOf(widthSize, heightSize, initialTextSize).min()!!)
}
fun EditText.afterTextChanged(afterTextChanged: (String) -> Unit) {
this.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /* nop */
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) { /* nop */
}
override fun afterTextChanged(editable: Editable?) {
afterTextChanged.invoke(editable.toString())
}
})
}
private var EditText.initialTextSize: Float
get() = getTag(INITIAL_TEXT_SIZE) as Float
set(value) {
setTag(INITIAL_TEXT_SIZE, value)
}
private val autoSizeBounds = Rect()
private const val INITIAL_TEXT_SIZE = 72846234
@ezamelczyk
Copy link
Author

The above gist automatically adjust font size to fit within the bounds of the EditText. It requires the text to be one-line only and the editText to have pre-set width (that means no wrap_content. It's not optimized but a single edittext shouldn't throttle even the lowest-end devices.

@ezamelczyk
Copy link
Author

Also worth noting - it breaks heavily for very small font sizes. Probably something related to floating point error, but I can't be bothered with fixing it since it isn't a real world use-case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment