TL; DR;
@Matt McMinn has already demonstrated a solution to this problem here , understand it. I will only repeat this decision here.
Please note that this problem has already been fixed at the platform level in Android 4.2.2. See the screenshots below for a comparison of words for the same code base, but different versions of the platform on the Galaxy Nexus.

Therefore, if you are not targeting older versions of Android, you may not use this fix at all.
The code
MainActivity.java
package com.example.nobr; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; import android.widget.TextView.BufferType; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView helloWorld = (TextView) findViewById(R.id.hello_world); helloWorld.setText(R.string.hello_world, BufferType.EDITABLE); TextView longText = (TextView) findViewById(R.id.long_text); longText.setText(R.string.long_text_with_url, BufferType.EDITABLE); } }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" > <com.example.nobr.NonBreakingPeriodTextView android:id="@+id/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.nobr.NonBreakingPeriodTextView android:id="@+id/long_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/hello_world" android:layout_below="@+id/hello_world" android:layout_marginTop="20dp" /> </RelativeLayout>
NonBreakingPeriodTextView.java
package com.example.nobr; import android.content.Context; import android.graphics.Paint; import android.text.Editable; import android.util.AttributeSet; import android.util.Log; import android.widget.TextView; public class NonBreakingPeriodTextView extends TextView { private static final String TAG = "NonBreakingPeriodTextView"; public NonBreakingPeriodTextView(Context context) { super(context); } public NonBreakingPeriodTextView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Editable editable = getEditableText(); if (editable == null) { Log.d(TAG, "non-editable text"); return; } int width = getWidth() - getPaddingLeft() - getPaddingRight(); if (width == 0) { Log.d(TAG, "zero-length text"); return; } Paint p = 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; while (strPos < editable.length()) { curWidth += widths[strPos]; char curChar = editable.charAt(strPos); if (curChar == newLine) { reset = true; } else if (Character.isWhitespace(curChar)) { lastWSPos = strPos; } else if (curWidth > width && lastWSPos >= 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) { setText(editable); } } }
Result
On Android 4.1.2 (Galaxy Nexus)

On Android 2.3.3 (AVD, Nexus One clone)

Hope this helps.
ozbek
source share