如何找到每行的TextView Text字符数?

Der*_*rek 20 size android text width textview

所以我在android中有一个TextView,它具有整个屏幕长度的宽度和一个dip 5的填充.我如何计算出适合屏幕上一行的字符数?我想换句话说,我正在尝试获取textview的列数?

我考虑了手工计算取决于文本大小和宽度,但是1)不知道相关性和2)由于以倾角为单位的填充,不同的屏幕将使用不同数量的实际像素来填充.

总体问题:我正在尝试使用它来解决:如果给出一个字符串,我怎样才能手动编辑为字符串,这样当textview逐字符打印字符串时,我将知道何时开始一个不适合一个字符的单词下一行.注意:我知道textview会自动放入不适合下一行的单词,但是,由于我是逐个字符打印,比如输入动画,textview不知道这个单词在打印出来之前是不适合的溢出的那个词的字符.

一直在寻找这个......

谢谢!

添加解决方案

一种可能的方案:

public String measure2 (TextView t, String s) {
    String u = "";
    int start = 0;
    int end = 1;
    int space = 0;
    boolean ellipsized = false;
    float fwidth = t.getMeasuredWidth();
    for(;;) {
        //t.setText(s.substring(start, end));
        float twidth = t.getPaint().measureText(s.substring(start, end));
        if (twidth < fwidth){
            if (end < s.length())
                end++;
            else {
                if (!ellipsized)
                    return s;
                return u + s.subSequence(start, end);
            }
        }
        else {
            ellipsized = true;
            space = (u + s.substring(start, end)).lastIndexOf(" ");
            if (space == -1)
                space = end - 1;
            u += s.subSequence(start, space) + "\n";
            start = space + 1;
            end = start + 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案2,但有时仍然使用solution1:

public String measure3 (TextView t, String s) {
    List<String> wlist = Arrays.asList(s.split(" "));
    if (wlist.size() == 1)
        return measure2(t, s);
    String u = "";
    int end = 1;
    float fwidth = t.getMeasuredWidth();
    for(;;) {
        //t.setText(s.substring(start, end));
        if (wlist.isEmpty())
            return u;
        String temp = listStr(wlist, end);
        float twidth = t.getPaint().measureText(temp);
        if (twidth < fwidth){
            if (end < wlist.size())
                end++;
            else {
                return u + temp;
            }
        }
        else {
            temp = listStr(wlist, end-1);
            if (end == 1)
                temp = measure2(t, temp);
            if (wlist.isEmpty())
                return u + temp;
            else
                u = u + temp + "\n";
            wlist = wlist.subList(end - 1, wlist.size());
            end = 1;
        }
    }
}

public String listStr (List<String> arr, int end) {
    String s = "";
    for (String e : arr.subList(0, end) ){
        s = s + e + " ";
    }
    return s.trim();
}
Run Code Online (Sandbox Code Playgroud)

我使用上面的代码生成一个原始字符串s,一个将被打印的字符串u.但是,我认为这种方法效率很低.还有其他方法或更好的算法吗?注意:我修复了measure3中的一些错误,但是懒得编辑

Ale*_*dam 28

试试这个:

private boolean isTooLarge (TextView text, String newText) {
    float textWidth = text.getPaint().measureText(newText);
    return (textWidth >= text.getMeasuredWidth ());
}
Run Code Online (Sandbox Code Playgroud)

由于字符的宽度可变,因此无法检测适合的字符数.上面的函数将测试TextView中是否符合特定字符串.newText的内容应该是特定行中的所有字符.如果为true,则启动一个新行(并使用新字符串作为参数传递).


回答评论:

  1. 因为应用程序可以在许多系统中运行,这正是您需要测量它的原因.
  2. 这是解决"整体问题"的一种方法.使用str.size()> numCol与isTooLarge有什么区别?您将需要实现动画(提示#1:插入换行符)
  3. 正如我之前所说,当你开始一个新的行时,你会开始一个新的字符串(提示#2:如果扩展TextView,你可以在覆盖中实现所有这些str.size()>numCol).(提示#3:跟踪用a创建的行setText并用于static int lines;检查长度).