Skip to content

Instantly share code, notes, and snippets.

@glureau
Created June 3, 2019 23:26
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save glureau/3ee4bba9a36fcf87e09467eb4e679b01 to your computer and use it in GitHub Desktop.
/**
* Method to adjust (auto-size) the text size AND the images height.
* This approach is based on width and lines instead of height, so you can use layout_heigt="wrap_content"
* and the TextView height will adapt to the best font size (instead of hardcoded heights).
* Idea of improvements: use layout_height value if hardcoded, and use current behaviour for match_parent or wrap_content.
*
* /!\ WARNING /!\
* You can define the min/max/granularity of autoSize with the standard appCompat definitions BUT you have to define the type to uniform.
* app:autoSizeTextType="uniform"
* app:autoSizeMaxTextSize="500sp"
* If you don't define type=uniform, the XML values will be ignored.
* /!\ WARNING /!\
*
* Also you can use this method with no autoSize parameters and it will work with the default values.
*/
@SuppressLint("RestrictedApi", "WrongConstant")
fun TextView.adjustSizeToFit(drawableHeightCompute: DrawableHeightComputeMode = AllLettersTextBoundsDrawableHeightComputeMode()) {
if (this !is AppCompatTextView) throw java.lang.IllegalStateException("You have to use AppCompatTextView to use adjustSizeToFit")
// Wait pre-draw to ensure the view width is ready
doOnPreDraw {
// Re-store previous configuration or create new one based on XML attributes
val autoSizeConfiguration = providesAutoSizeConfiguration()
// Force enable the autosize so the base (AppCompat)TextView will generate auto text sizes (will use default values, not XML ones)
// downcast required for <26 api (will target hidden API)
(this as AppCompatTextView).setAutoSizeTextTypeUniformWithConfiguration(
safeAutoSizeMinTextSize(autoSizeConfiguration), safeAutoSizeMaxTextSize(autoSizeConfiguration),
safeAutoSizeStepGranularity(autoSizeConfiguration), TypedValue.COMPLEX_UNIT_PX
)
val bestSize = findLargestTextSizeWhichFitsWidth(
width.toFloat() - totalPaddingStart - totalPaddingEnd,
drawableHeightCompute
)
// Force disable autosize as we'll override the default behaviour by setting the size manually.
// downcast required for <26 api (will target hidden API)
(this as AppCompatTextView).setAutoSizeTextTypeWithDefaults(TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
setTextSize(TypedValue.COMPLEX_UNIT_PX, bestSize.toFloat())
// Requires a last update with final textPaint (edge case when the last try is too big)
alignImageToText(paint, drawableHeightCompute)
// As we've probably changed the height, we need to request layout update.
requestLayout()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment