Sunday, August 27, 2017

TextView breaks my word by letters

Leave a Comment

My requirements: create "incoming bubble" with width by content and max width 90%.

I have this markup:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:orientation="horizontal"     android:weightSum="1.0"     tools:background="@color/white_smoke">      <LinearLayout         android:id="@+id/flBubble"         android:layout_width="0dp"         android:layout_height="wrap_content"         android:layout_gravity="start"         android:background="@drawable/bubble_in"         android:layout_weight="0.9">          <ImageView             android:id="@+id/ivSay"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:background="?android:attr/selectableItemBackground"             android:contentDescription="@string/default_content_description"             android:padding="8dp"             android:src="@drawable/ic_play_circle_outline_black_24dp"             android:tint="@color/primary"/>          <TextView             android:id="@+id/tvValue"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_gravity="center_vertical"             android:padding="8dp"             android:textColor="@color/black"             android:textSize="16sp"             tools:text="I would like to go to an Italian restaurant"/>     </LinearLayout>      <View         android:layout_width="0dp"         android:layout_height="0dp"         android:layout_weight="0.1"/> </LinearLayout> 

Sometimes I get the following result: bad word wrapping

But I expect the following result (it's falsely encouraging screenshot from Android Studio preview): expected word wrapping

How can I prevent breaking word restaraunt by letters?

UPDATE

Although I use minSdk=15 I tried to use breakStrategy and I haven't get expected result. android:breakStrategy="simple": simple break strategy

android:breakStrategy="balanced": balanced break strategy

I found a related question: Force next word to a new line if the word is too long for the textview, but I didn't undestand how can I get maximum available width for TextView with layout_width="wrap_content?

It would be great if I could override the TextView.setText and place line breaks there if needed.

7 Answers

Answers 1

You can use webview to achieve this behavior. In webview you can use css to adjust text. Take a look at this answer


Update

You can calculate width of string and add \n to string where is string needs to split

Rect bounds = new Rect();  Paint textPaint = textView.getPaint();   textPaint.getTextBounds(text, 0, text.length(), bounds);   int height = bounds.height();  int width = bounds.width(); 

Results is in pixels, so just check width of your view or screen and split the string.


UPDAE2: Example Code

I just wrote an example with simple layout in activity onCreate you can implement it in adapter or whatever works for you.

    TextView textView = (TextView) findViewById(R.id.txt); //textview with empty text     Rect bounds = new Rect();     Paint textPaint = textView.getPaint();      String text = "some long text here.....";// text data to work on     textPaint.getTextBounds(text, 0, text.length(), bounds);     int textWidth = bounds.width();// get text width in pixel     int marginPadding = 100;// we have some padding and margin from xml layouts     DisplayMetrics displayMetrics = new DisplayMetrics();     getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);     int rootWidth = displayMetrics.widthPixels-marginPadding;// maximum width on screan      if (textWidth > rootWidth) { // check if need to split the string.         int lineMax = (text.length() * rootWidth) / textWidth; // maximum Characters for each line         String result = text.replaceAll("(.{" + String.valueOf(lineMax) + "})", "$1\n"); // regex to replace each group(lineMax) of Chars with group of char + new line         textView.setText(result);     } else         textView.setText(text); 

UPDATE#3: Fixed code for Listview

onCreate

    ArrayList<String> data = new ArrayList<>();      data.add("000");     data.add("aaaaaaaaaaa");     data.add("aaaaaaaaaaa bbbbbbbbbbbb");     data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc");     data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd");     data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee");     data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee ffffffffffffffffff");     data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee ffffffffffffffffff gggggggggggggggg");     data.add("aaaaaaaaaaa bbbbbbbbbbbb cccccccccccccccc ddddddddddddd eeeeeeeeeeeee ffffffffffffffffff gggggggggggggggg hhhhhhhhhhhhhhhh");      ListView listView = (ListView) findViewById(R.id.listview);     MyAdapter adapter= new MyAdapter(data,this);     listView.setAdapter(adapter);     adapter.notifyDataSetChanged(); 

MyAdapter.java

public class MyAdapter extends BaseAdapter {  private LayoutInflater inflater = null; Context context; ArrayList<String> data;   public MyAdapter(ArrayList<String> data, Context context) {     this.context = context;     this.data = data;     inflater = (LayoutInflater) context             .getSystemService(Context.LAYOUT_INFLATER_SERVICE); }  @Override public int getCount() {     return data.size(); }  @Override public Object getItem(int i) {     return data.get(i); }  @Override public long getItemId(int i) {     return i; }   @Override public View getView(final int i, View convertView, ViewGroup viewGroup) {      final View view = inflater.inflate(R.layout.item, null);     final TextView tv_text = (TextView) view.findViewById(R.id.tvValue);     if (data.get(i) != null) {         tv_text.post(new Runnable() {             @Override             public void run() {                //TextView is Ready to be used.                 fixText(data.get(i),tv_text);             }         });     }     return view; }      private void fixText(String text, TextView textView) {     Rect bounds = new Rect();     Paint textPaint = textView.getPaint();     textPaint.getTextBounds(text, 0, text.length(), bounds);     int textWidth = bounds.width();// get text width in pixel     int marginPadding = 100;// we have some padding and margin from xml layouts     DisplayMetrics displayMetrics = new DisplayMetrics();     ((MainActivity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);     int rootWidth =  textView.getWidth();//displayMetrics.widthPixels - marginPadding;// maximum width on screan      if (textWidth > rootWidth) { // check if need to split the string.         //int lineMax = (text.length() * rootWidth) / textWidth; // maximum Characters for each line         //String result = text.replaceAll("(.{" + String.valueOf(lineMax-5) + "})", "$1\n"); // regex to replace each group(lineMax) of Chars with group of char + new line         String result = wrapText(rootWidth,text);         textView.setText(result);     } else         textView.setText(text);    }  private String wrapText(int textviewWidth,String mQuestion) {     String temp = "";     String sentence = "";     String[] array = mQuestion.split(" "); // split by space     for (String word : array) {         if ((temp.length() + word.length()) < textviewWidth) {  // create a temp variable and check if length with new word exceeds textview width.             temp += " "+word;         } else {             sentence += temp+"\n"; // add new line character             temp = word;         }     }     return (sentence.replaceFirst(" ", "")+temp); } 

item.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:weightSum="1.0" tools:background="@color/colorAccent">  <LinearLayout     android:id="@+id/flBubble"     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_gravity="start"     android:background="@color/colorPrimary"     android:layout_weight="0.9">      <ImageView         android:id="@+id/ivSay"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:background="?android:attr/selectableItemBackground"         android:contentDescription="default_content_description"         android:padding="8dp"         android:src="@android:drawable/ic_media_play"         android:tint="@color/colorPrimaryDark" />      <TextView         android:id="@+id/tvValue"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="center_vertical"         android:padding="8dp"         android:textColor="#000000"         android:textSize="16sp"         tools:text="I would like to go to an Italian restaurant jkjk l;'"/> </LinearLayout>  <View     android:layout_width="0dp"     android:layout_height="0dp"     android:layout_weight="0.1"/> </LinearLayout> 

Result in device

Answers 2

Use MaxWidth property for textview or else you should provide width for textview

   <com.custom.views.CustomTextView         android:id="@+id/txt_send_chat"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center_vertical"         android:gravity="center_vertical"         android:maxWidth="250dp"         android:textColor="@color/color_chat_sender"         android:textSize="16sp"         app:font_name="@string/font_roboto_regular" /> 

Answers 3

Try this

<TextView         android:id="@+id/tvValue"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_gravity="center_vertical"         android:padding="8dp"         android:textColor="@color/black"         android:textSize="16sp"         tools:text="I would like to go to an Italian restaurant"/> </LinearLayout> 

Answers 4

You can try with Autosizing TextViews

The Support Library 26.0 provides full support to the autosizing TextView feature on devices running Android versions prior to Android 8.0 (API level 26). The library provides support to Android 4.0 (API level 14) and higher. The android.support.v4.widget package contains the TextViewCompat class to access features in a backward-compatible fashion

For Example:

<TextView     android:layout_width="match_parent"     android:layout_height="200dp"     android:autoSizeTextType="uniform" /> 

For more details Guidelines go HERE

Their is Library too HERE

Answers 5

Change your TextView to EditText and put this 2 lines. it should help you

    android:inputType="textMultiLine"     android:enabled="false" 

This will place you text properly and later on you can give a edit feature in your application if you need.

Answers 6

Try like this ;

String htmlText = " %s "; String myData = "Hello World! This tutorial is to show demo of displaying text with justify alignment in WebView."; WebView webView = (WebView) findViewById(R.id.webView1); webView.loadData(String.format(htmlText, myData), "text/html", "utf-8"); 

Answers 7

Sorry couldn't comment,

try this:

android:inputType="textMultiLine" 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment