6

I want to show text dynamically in a TextView. The text will come from the server dynamically. This may be a single word or a single line or a paragraph. The text is displaying the view with size as 56sp based on customer requirement.

My issue here is, the application displaying the text in a huge size. In the case of word break at the end of the line, OS is not showing a hyphen("-") automatically in below Marshmallow devices.

eg: Text: "Carryover data now available" It's showing in the UI as

Carryover

data now ava

ilable

I want to show this as

Carryover

data now ava-

ilable.

But this is properly working in Marshmallow or above devices.

TextView property is given below

<TextView
     android:id="@+id/tv_primary_headline"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_alignParentTop="true"
     android:fontFamily="sans-serif-black"
                  android:lineSpacingExtra="@dimen/promo_primarytext_line_spacing"
     android:textAppearance="?android:attr/textAppearanceLarge"
     android:textColor="@color/navigation_selection_color"
     android:textSize="@dimen/promo_primary_headline_size"
     android:textStyle="bold"
     android:visibility="visible" />

 TextView mTvPrimaryHeadline = (TextView) view.
                    findViewById(R.id.tv_primary_headline);
  this.mTvPrimaryHeadline.setText(Html.fromHtml(title));
Nithinjith
  • 1,775
  • 18
  • 40
  • 1
    Possible duplicate of [Hyphenation in Android](http://stackoverflow.com/questions/4454911/hyphenation-in-android) – rds Oct 27 '16 at 08:45
  • Is it any option to show "-" in below 6 devices. I tried Soft-Hyphen, but it's not working. The GitHub library implementation is quite confusing and it's won;t have a License. If, possible please share the code. This will helpful for my development. – Nithinjith Oct 27 '16 at 11:55
  • In my implementation, I can't add get the strings from string.xml. The values are coming from JSON response. So Is it possible to create a java level hyphenation in the case of overflow words?. – Nithinjith Oct 27 '16 at 12:21

2 Answers2

3

I implement an alternate way to fix this issue.

To generalize the implementation for all devices, dynamically arrange the text based on the longest word in the sentence. Please use the below two methods and pass the complete sentence and using TextView. This will automatically arrange the text for all the devices for all screens.

/**
     *
     * @param message - Raw Header message from Server - Sentance/ Paragraph.
     *              The message will split and rearrange the size based on its character length
     */
    private void updateText(String message, TextView mTvMessageText ) {
        try {
            if (message == null || message.length() == 0) {
                return;
            }

            String word = getLongestWordLength(message);

            if (word == null) {
                return;
            }
            String wordUpper = word.toUpperCase();// Convert the word to uppercase to find the Maximum Space
            // mTvMessageText - TextView need to Update the Value
            float width = ((mTvMessageText.getMeasuredWidth()) - 120); // Get the width of the View with reduced padding
            float textWidth = mTvMessageText.getPaint().measureText(wordUpper); // Get the word Holding Space through Paint
            float textSizeInPixel = getResources().getDimension(R.dimen.message_size); // Get dimension text Size - My Size is 65sp
            float lineSpacingExtra = getResources().getDimension(R.dimen.message_line_spacing); //High text size required Negative Line Spacing initially -15

            /**
             * Loop will reduce the font size of actual 3% in each looping
             * The looping condition is the longest word in the sentence to hold in a single line of View
             * Reduce the Inline space with accordingly
             * Submit the reduced amount of size in the textView and check the holding pixels
             * If the holding pixels are up above the total pixel size, the loop will continue
             */
            while (textWidth > width) {
                textSizeInPixel -= textSizeInPixel * (0.03); // Reduce the Fount Size with 3% each looping
                lineSpacingExtra += Math.abs(lineSpacingExtra) * (0.06); // Reduce the minus space extra
                this.mTvMessageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSizeInPixel);
                this.mTvMessageText.setLineSpacing(lineSpacingExtra, 1f);
                textWidth = mTvMessageText.getPaint().measureText(wordUpper);// Assign value to measure the text Size
            }

            /**
             * M & N devices has a property to rearrange the word with hyphenation
             * In Order to avoid the same, Application will add this logic
             */
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mTvMessageText.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
            }

            /**
             * Text Set Using from Html
             */

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                this.mTvMessageText.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
            } else {
                this.mTvMessageText.setText(Html.fromHtml(message));
            }
        } catch (Resources.NotFoundException e) {
            Log.e(TAG, e.getMessage());
        }

    }


    /**
     *
     * @param wordString - Raw String with Multiple word
     *                   This may be a header
     *                   May be a paragraph
     *                   May be contain Multiple Paragraphs
     * @return - Identify the Longest word and return the length of it
     */
    private String getLongestWordLength(String wordString) {
        try {
            if (wordString == null) {
                return null;
            }
            if (wordString.length() == 0) {
                return null;
            }
            String[] splitArray = wordString.split(" ");

            String word = "";

            for (int i = 0; i < splitArray.length; i++) {
                if (splitArray[i].length() > word.length()) {
                    word = splitArray[i];
                }
            }
            return word;
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
        return null;
    }
Nithinjith
  • 1,775
  • 18
  • 40
-1

It will work for two lines can me made for multiline but not sure for Recycleview

package com.example.myapplication;
import android.content.Context;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import android.widget.TextView;

public class DashTextView extends TextView {
public DashTextView(Context context) {
    super(context);
}

public DashTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public DashTextView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

public void setDashedText(final CharSequence text) {
    super.setText(text);
    getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                getViewTreeObserver().removeOnGlobalLayoutListener(this);
                if (getLineCount() > 1) {
                    int widthLimit = getWidth() - getPaddingLeft() - getPaddingRight();
                    StaticLayout tempStaticLayout = new StaticLayout(getText(), getPaint(),
                            widthLimit, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);

                    int lineEndIndex = tempStaticLayout.getLineEnd(0);

                    String text = String.valueOf(getText().subSequence(0, lineEndIndex));
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(text)
                            .append("-")
                            .append(getText().subSequence(lineEndIndex, getText().length()));
                    DashTextView.super.setText(stringBuilder.toString());
                }
            }
        }
    });
}
}
Vipin Sahu
  • 1,441
  • 1
  • 18
  • 29