Don't wrap text in Android TextView at period in abbreviation

北慕城南 提交于 2019-11-26 23:09:56

问题


Is there a way to control where a TextView chooses to wrap its text? The issue that I'm having is that it wants to wrap at periods - so a string like "Available in the U.S. and Canada" could wrap after the period between the U and the S. Is there a way to tell the TextView not to wrap unless there's a period and a space, or some programmatic way to control the wrapping?


回答1:


I ended up writing my own algorithm to break the text only on whitespace. I had originally used the breakText method of Paint, 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 TextView, I just call this from the onSizeChanged method to ensure that there's a valid width.

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 > width.  Replace the whitespace with a newline and reset 
    //the counter.

    while(strPos < 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 > 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)
    {
         tv.setText(editable);
    }
}



回答2:


There is a spannable called WrapTogetherSpan. There's no documentation on it, but it sounds like text inside one shouldn't wrap.



来源:https://stackoverflow.com/questions/14373157/dont-wrap-text-in-android-textview-at-period-in-abbreviation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!