如果单词对于textview来说太长,则强制下一个单词到新行

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果单词对于textview来说太长,则强制下一个单词到新行相关的知识,希望对你有一定的参考价值。

我有一个TextView,当以编程方式填充时,将无法正确排列单词。

Current Output:

这就是发生的事情:

| Hi I am an examp |
| le of a string t |
| hat is not break |
| ing correctly on |
| words            |

Expected Output:

我要这个:

| Hi I am an       |
| example of a     |
| string that is   |
| breaking         |
| correctly on     |
| words            |

Java:

String mQuestion = "Hi I am an example of a string that is breaking correctly on words";
mTextView.setText(mQuestion);

XML:

<LinearLayout
    android:id="@+id/questionContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/questionHeaderTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/header_bg"
        android:paddingBottom="10dp"
        android:paddingLeft="25dp"
        android:paddingTop="10dp"
        android:text="@string/category_hint"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Space
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".05" />

        <!-- THIS ONE WILL NOT WRAP !-->
        <TextView 
            android:id="@+id/questionHolderTextView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".9"
            android:layout_marginBottom="15dp"
            android:layout_marginTop="15dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:text="@string/question_holder"
            android:singleLine="false"
            android:scrollHorizontally="false"
            android:ellipsize="none"
            android:textSize="20sp" />

        <Space
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight=".05" />

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_marginTop="5dp"
        android:background="@color/black" />
</LinearLayout>

<LinearLayout
    android:id="@+id/answerContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:visibility="visible" >
</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:layout_marginTop="25dp"
    android:gravity="center" >

    <Button
        android:id="@+id/nextButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="25dp"
        android:text="@string/next" />
</LinearLayout>

答案

首先你可以使用TextView.getPaint()获取文本绘画,然后每次添加一个新单词(嗨,我,我等),在绘画上调用measureText。如果结果长度超过TextView的可用宽度,请在新单词前添加\n。重置数据并重复步骤。

另一答案

我最终使用了

private void initView() {
        Paint paint = new Paint();
        float width = paint.measureText(mQuestion);
        int maxLength = 300; // put whatever length you need here
        if (width > maxLength) {
            List<String> arrayList = null;
            String[] array = (mQuestion.split("\\s"));
            arrayList = Arrays.asList(array);
            int seventyPercent = (int) (Math.round(arrayList.size() * 0.70)); // play with this if needed
            String linebreak = arrayList.get(seventyPercent) + "\n";
            arrayList.set(seventyPercent, linebreak);
            mQuestion = TextUtils.join(" ", arrayList);
            mQuestion.replace(",", " ");
        }
        mQuestionHolderTextView.setText(mQuestion);
    }

我测量字符串,将其转换为List,然后将其拆分为70%并创建一个新行。然后我将List转回String并删除逗号。只要这个单词不超过剩余行数的30%就可以清除,否则会相应调整。

它快速而肮脏,但它对我有用。

另一答案

使用以下方法,您可以获取包装文本。

因为我没有设置android,所以我编写了一个Test类并从main调用了该方法。您需要传递textview宽度。我在这里过了14分。

    public class Test{


    public static void main(String[] args) {
        String wrappedText=wrapText(14);
        System.out.println(wrappedText);
    }

    public static String wrapText(int textviewWidth) {

        String mQuestion = "Hi I am an example of a string that is breaking correctly on words";


        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);

    }

}

输出 -

Hi I am an
example of a
string that is
breaking
correctly on
words
另一答案

感谢suitianshi,下面是我的解决方案。

 private String getWidthFitString(String input) {
    Paint paint = text.getPaint();
    // you can define max width by yourself
    int maxWidth = getContentMaxWidth(); 
    float width = paint.measureText(input);
    if (width > maxWidth) {
        List<String> words = Arrays.asList(input.split("\\s"));
        int breakLinePosition = 0;
        String toBreakLineText;
        List<String> toBreakLineWords = new ArrayList<>();
        while (breakLinePosition < words.size()) {
            toBreakLineWords.add(words.get(breakLinePosition));
            toBreakLineText = TextUtils.join(" ", toBreakLineWords);
            float currentWidth = paint.measureText(toBreakLineText);
            if (currentWidth > maxWidth) {
                break;
            }
            breakLinePosition ++;
        }
        if (breakLinePosition > 1) {
            toBreakLineWords.remove(toBreakLineWords.size() - 1);
            toBreakLineText = TextUtils.join(" ", toBreakLineWords);
            List<String> fromBreakLineWords = new ArrayList<>();
            for (int i = breakLinePosition; i < words.size(); i++) {
                fromBreakLineWords.add(words.get(i));
            }
            return toBreakLineText + "\n" + getWidthFitString(TextUtils.join(" ", fromBreakLineWords));
        } else {
            return input;
        }
    }
    return input;
}

它工作和清洁代码。

以上是关于如果单词对于textview来说太长,则强制下一个单词到新行的主要内容,如果未能解决你的问题,请参考以下文章

android TextView:如何避免换行?

Reportlab - 如果段落对于一行来说太长,如何引入换行符

根据屏幕宽度修剪单词

同一个TextView中的多个id

word-break和word-wrap

为啥这个值对于我的 H2 表来说太长了