 <p>I ended up writing my own algorithm to break the text only on whitespace. I had originally used the <a href="http://developer.android.com/reference/android/graphics/Paint.html#breakText%28java.lang.CharSequence,%20int,%20int,%20boolean,%20float,%20float%5b%5d%29">breakText</a> method of <a href="http://developer.android.com/reference/android/graphics/Paint.html">Paint</a>, but was having some issues (that may actually be resolved in this version of the code, but that's OK). This isn't my best chunk of code, and it could definitely be cleaned up a bit, but it works. Since I'm overriding <a href="http://developer.android.com/reference/android/widget/TextView.html">TextView</a>, I just call this from the <a href="http://developer.android.com/reference/android/view/View.html#onSizeChanged%28int,%20int,%20int,%20int%29">onSizeChanged</a> method to ensure that there's a valid width.</p> <pre class="lang-js prettyprint-override"><code>private static void breakManually(TextView tv, Editable editable) { int width = tv.getWidth() - tv.getPaddingLeft() - tv.getPaddingRight(); if(width == 0) { // Can't break with a width of 0. return false; } Paint p = tv.getPaint(); float[] widths = new float[editable.length()]; p.getTextWidths(editable.toString(), widths); float curWidth = 0.0f; int lastWSPos = -1; int strPos = 0; final char newLine = '\n'; final String newLineStr = "\n"; boolean reset = false; int insertCount = 0; //Traverse the string from the start position, adding each character's //width to the total until: //* A whitespace character is found. In this case, mark the whitespace //position. If the width goes over the max, this is where the newline //will be inserted. //* A newline character is found. This resets the curWidth counter. //* curWidth &gt; width. Replace the whitespace with a newline and reset //the counter. while(strPos &lt; editable.length()) { curWidth += widths[strPos]; char curChar = editable.charAt(strPos); if(((int) curChar) == ((int) newLine)) { reset = true; } else if(Character.isWhitespace(curChar)) { lastWSPos = strPos; } else if(curWidth &gt; width &amp;&amp; lastWSPos &gt;= 0) { editable.replace(lastWSPos, lastWSPos + 1, newLineStr); insertCount++; strPos = lastWSPos; lastWSPos = -1; reset = true; } if(reset) { curWidth = 0.0f; reset = false; } strPos++; } if(insertCount != 0) { tv.setText(editable); } } </code></pre>