Search code examples
androidtextviewandroid-4.2-jelly-beanbounds

Android jelly bean text view with custom font ,not fitting


Just for the info ,I have gone all the resources that tells how to fit text within bounds

  1. Auto Scale TextView Text to Fit within Bounds
  2. How to scale/resize text to fit a TextView?
  3. How to adjust text font size to fit textview
  4. Android font size difference issue on gingerbread and jellybeans

But my main problem is that I don't want to resize the font to fit within text bounds.What I have is a TextView which takes a Custom Font from assets folder.Further the user is able to change the font size via slider.All the devices lower than Jelly Bean there seems no problem,but Jelly Bean devices the text doesn't fit the bounds of the TextView as shown in the image textview not fitting

Further neither of purposed solution as stated on stackoverflow answers do any good.Somehow some of the solution simply lowers down the font size to fit within bounds. I do not want to lower font size,instead I want to do the following

  1. Calculate the length of the text that fits on the width of the screen
  2. Then append newline to the string at that particular length
  3. Since the text length will be large,I am afraid to use StringBuffer and StringBuilder as they could easily result in out of memory exception
  4. So the TextView automatically calculates the factor inserts news line when reaches the visible length.

So far I am able to break down text,by calculating a factor which helps to find the minimum amount of words that fit on width of the screen.But ,this it results in words being broken meaning Hello can result into Hel in one line and other line continued by lo.

public class AutoResizeTextView extends TextView {

private boolean forFirstTime = true;

    @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if (forFirstTime)
        monitorChanges();
}



private void monitorChanges() {
    final int widthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
            - getCompoundPaddingRight();
    if (widthLimit <= 0) {
        return;
    }
    final String mainText = getText().toString();
    final float actualTextWidth = getPaint().measureText(mainText);

    forFirstTime = false;

    setText("");
    String[] overallText = inputText.split("\\n");

    for(int j=0;j<overallText.length;j++){
        String mainText =overallText[j];
        int length = mainText.length();
        int lineNumber = Math.round(getPaint().measureText(mainText)/ widthLimit);
        int wordLimit = (int) Math.round(length / (lineNumber * 1.3));
        //wordLimit+=2;
        if (wordLimit < length) {
            int count = Math.round(length / wordLimit);
            int startIndex = -1, endIndex = -1;
            for (int i = 0; i < count; i++) {
                startIndex = wordLimit * i;
                endIndex = wordLimit * (i + 1);
             append(mainText.substring(startIndex, endIndex) + "\n");
            }
        append(mainText.toString().substring(endIndex, length)+"\n");
        }
   }
}

Now I want the words not be broken,as exhibited by default android EditText on wrap_content params,where the whole text is moved to next line,if it becomes large to fit. And further the formula for calculating the wordLimit is not accurate,I just want to find out the exact length of the string that fits the widthLimit of TextView/EditText

I am also working on it and if anything comes,I will surely post.


Solution

  • I don't know this is the right solution or not.But so far,text is rendered well and no text cut off i.e. text shown within bounds.

    public class AutoResizeTextView extends TextView {
    
    
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (forFirstTime)
            monitorChanges();
    }
    
    private boolean forFirstTime = true;
        // Text view line spacing multiplier
        private float mSpacingMult = 1.0f;
    
        // Text view additional line spacing
        private float mSpacingAdd = 0.0f;
    
    private void monitorChanges() {
        int widthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
                - getCompoundPaddingRight();
    
        if (widthLimit <= 0) {
            return;
        }
        String inputText = getText().toString();
    
        forFirstTime = false;
    
        setText("");
        String[] overallText = inputText.split("\\n");
    
        TextPaint textPaint = getPaint();
        for(int j=0;j<overallText.length;j++){
            String mainText =overallText[j];
            StaticLayout layout = new    StaticLayout(mainText,textPaint,widthLimit,Alignment.ALIGN_NORMAL,
                    mSpacingMult,mSpacingAdd,false);        
            if(layout.getLineCount()>0){
                for(int i=0;i<layout.getLineCount();i++){
                    int start =layout.getLineStart(i);
                    int end =layout.getLineEnd(i);
                    append(mainText.substring(start, end)+"\n");
                }
            }
    
        }   
    }
    }
    

    But I am not completely satisfied with the result ;)