grantland/android-autofittextview — pull request #8 by drbild (2014-03-18 23:19:32+00:00)
Title: Compute font size in onMeasure() to support height, line spacing, drawables, etc.

The previous version used a separate StaticLayout to determine if the
text was too large for the desired TextView height. However,
accurately mimicing the TextView appearance (and thus size) is nearly
impossible when one considers full information, e.g., line spacing,
left/right/top/bottom drawables, replacement spans, etc. Before API
16, information like line spacing was simply unavailable to
subclasses.

This commit uses a different approach. The onMeasure() method is
overriden to tell the superclass TextView to measure at its desired
height. If this is too tall or short (in pixels or lines), the font is
decreased or increased and the view measured again. The same binary
search process as before is used.

This commit does not work when the 'android:singleLine' attribute is
set. The text is clipped. Instead, 'android:maxlines="1"' should be
set and the desired ellipsizing, horizontal scrolling, and single-line
transforms set manually.

The TextView treats 'singleLine' as a special case (i.e., it's handled
differently than 'android:maxLines="1"'), but does not expose this
state. Ideally, we would disable 'singleLine' in onMeasure(), before
calling super.onMeasure(), and reenable it after setting the fitted
font size. However, as there is no (supported) way to determine if the
'singleLine' property was set, this is not possible. Simply disabling
maxLines and ellipsizing does not work---I belive because the TextView
uses the cached internal StaticLayout.

Ultimately, using 'singleLine' in an autosizing text view is weird
anyway, since 'singleLine' implies 'ellipsized'. (Ellipizing after
the font size has reached the minimum is still supported).